I noticed that in my Android app, after navigating away from a fragment, the onCreate()
and onDestroy()
methods are still called. This causes my code to throw an exception as the onDestroy()
method refers to resources(specifically, my ViewModel
) which are unavailable when the fragment is navigated away from.
public class InfoFragment extends Fragment {
private InfoViewModel viewModel;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(TAG, "onCreate");
/* ... other initialization code ... */
}
@Override
public void onDestroy() {
super.onDestroy();
Log.e(TAG, "onDestroy");
viewModel.performOperation(); // NullPointerException occurs after fragment is navigated away from, and screen is rotated
}
(do note that these are not the real names of the fragment and viewmodel)
Why is onCreate()
and onDestroy()
of my fragment still called after navigating away from it? Could this be a memory leak?
EDIT: Here is my crash log.
java.lang.RuntimeException: Unable to destroy activity {com.example.app/com.example.app.ui.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'androidx.lifecycle.MutableLiveData com.example.app.ui.InfoViewModel.performOperation()' on a null object reference
at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:4551)
at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:4569)
at android.app.ActivityThread.handleRelaunchActivityInner(ActivityThread.java:4853)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4786)
at android.app.servertransaction.ActivityRelaunchItem.execute(ActivityRelaunchItem.java:69)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:113)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:71)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1858)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:201)
at android.app.ActivityThread.main(ActivityThread.java:6820)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:922)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'androidx.lifecycle.MutableLiveData com.example.app.ui.InfoViewModel.performOperation()' on a null object reference
at com.example.app.ui.InfoFragment.onDestroy(InfoFragment.java:202)
at androidx.fragment.app.Fragment.performDestroy(Fragment.java:2927)
at androidx.fragment.app.FragmentStateManager.destroy(FragmentStateManager.java:492)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1296)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1356)
at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1434)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1504)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2625)
at androidx.fragment.app.FragmentManager.dispatchDestroy(FragmentManager.java:2609)
at androidx.fragment.app.Fragment.performDestroy(Fragment.java:2922)
at androidx.fragment.app.FragmentStateManager.destroy(FragmentStateManager.java:492)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1296)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1356)
at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1434)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1497)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2625)
at androidx.fragment.app.FragmentManager.dispatchDestroy(FragmentManager.java:2609)
at androidx.fragment.app.FragmentController.dispatchDestroy(FragmentController.java:330)
at androidx.fragment.app.FragmentActivity.onDestroy(FragmentActivity.java:365)
at androidx.appcompat.app.AppCompatActivity.onDestroy(AppCompatActivity.java:242)
at android.app.Activity.performDestroy(Activity.java:7524)
at android.app.Instrumentation.callActivityOnDestroy(Instrumentation.java:1307)
at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:4536)
... 13 more
This exception does not happen when the fragment is still the current fragment, but only when the user navigates away from it to other fragments through a bottom navigation bar.
Edit: To clarify, I am not asking why the crash happened(the crash can even be ignored), I want to know why the onCreate
and onDestroy
methods are still called after the fragment is navigated away from. The fragment is supposed to be destroyed after it is navigated away, but it seems that it is still running as I still receive logs from logcat for both onCreate and onDestroy. Why is this happening?
Thanks.
Your log showing
and your viewmodel isn't declare yet, try to declare it inside onCreate method