Today I noticed a strange behavior in my application.
It happens when I stop my application using Devices view from Eclipse. Can someone explain it?
Why is onActivityCreated()
of Fragment
called even when Activity
is already destroyed?
MyHomeActivity
contains two Fragment
s and similar log is generated for both.
Here I am pasting logs for one Fragment
.
NullPointerException
is a secondary problem.
I am surprised why onActivityCreated()
is called when the call stack was initiated from onDestroy()
of MyHomeActivity
?
03-05 12:31:21.414: W/System.err(5638): java.lang.NullPointerException
03-05 12:31:21.421: W/System.err(5638): at **MyListViewFrag.onActivityCreated**(BuddyListViewFrag.java:85)
03-05 12:31:21.421: W/System.err(5638): at android.support.v4.app.Fragment.performActivityCreated(Fragment.java:1468)
03-05 12:31:21.421: W/System.err(5638): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:931)
03-05 12:31:21.421: W/System.err(5638): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1088)
03-05 12:31:21.421: W/System.err(5638): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1070)
03-05 12:31:21.421: W/System.err(5638): at android.support.v4.app.FragmentManagerImpl.dispatchReallyStop(FragmentManager.java:1888)
03-05 12:31:21.421: W/System.err(5638): at android.support.v4.app.FragmentActivity.onReallyStop(FragmentActivity.java:787)
03-05 12:31:21.421: W/System.err(5638): at android.support.v4.app.FragmentActivity.doReallyStop(FragmentActivity.java:764)
03-05 12:31:21.421: W/System.err(5638): at android.support.v4.app.FragmentActivity.onDestroy(FragmentActivity.java:322)
03-05 12:31:21.421: W/System.err(5638): at MyFragmentActivity.onDestroy(RbrFragmentActivity.java:57)
03-05 12:31:21.421: W/System.err(5638): at **MyHomeActivity.onDestroy**(MyHomeActivity.java:254)
03-05 12:31:21.421: W/System.err(5638): at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:2663)
03-05 12:31:21.421: W/System.err(5638): at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:2694)
03-05 12:31:21.421: W/System.err(5638): at android.app.ActivityThread.access$2100(ActivityThread.java:117)
03-05 12:31:21.421: W/System.err(5638): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:968)
03-05 12:31:21.421: W/System.err(5638): at android.os.Handler.dispatchMessage(Handler.java:99)
03-05 12:31:21.421: W/System.err(5638): at android.os.Looper.loop(Looper.java:130)
03-05 12:31:21.421: W/System.err(5638): at android.app.ActivityThread.main(ActivityThread.java:3687)
03-05 12:31:21.429: W/System.err(5638): at java.lang.reflect.Method.invokeNative(Native Method)
03-05 12:31:21.429: W/System.err(5638): at java.lang.reflect.Method.invoke(Method.java:507)
03-05 12:31:21.429: W/System.err(5638): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
03-05 12:31:21.429: W/System.err(5638): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
03-05 12:31:21.429: W/System.err(5638): at dalvik.system.NativeStart.main(Native Method)
I am using support library for providing Fragment
s to pre-HoneyComb devices, if that makes any difference.
onDestroy()onDestroy() called to do final clean up of the fragment's state but Not guaranteed to be called by the Android platform.
onActivityCreated(Bundle) tells the fragment that its activity has completed its own Activity. onCreate() .
onCreate is called on initial creation of the fragment. You do your non graphical initializations here. It finishes even before the layout is inflated and the fragment is visible. onCreateView is called to inflate the layout of the fragment i.e graphical initialization usually takes place here.
The Fragment. setRetainInstance() method control whether a fragment instance is retained across Activity re-creation (such as from a configuration change). This can only be used with fragments not in the back stack.
After some testing and reviewing FragmentManager.moveToState, I believe that when the Fragment
is being handled by a FragmentPagerAdapter
, it is unavoidable that a Fragment
which was previously coalesced into savedState (as part of the process of stopping the app before you kill the process from the DDMS tab in eclipse), must first be "created" (in the terminology of FragmentManager
) before it can be destroyed.
This may actually be an unintended consequence of the process of rebuilding the fragments from saved state. When the FragmentActivity
is executing onCreate
and finish()
is called, the intention is that the FragmentActivity
stops setting up and exits. The visual experience is that this occurs, but it seems like the FragmentManager
takes it on itsself to continue the lifecycle for previously existing Fragment
s, albiet with some short cuts. This process seems to execute the lifecycle methods up to onActivityCreated
and then execute onDestroy
and onDetach
, skipping those in between.
The best way to handle this appears to be to address the secondary issues (in this case, your NPE) caused by this startup. It seems like there would be room to optimize this out of the Fragment
lifecycle, but with the r12 support library, the situation appears to be a consequence of the design.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With