Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fragment's onActivityCreated() is called after onDestroy() of Activity

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 Fragments 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 Fragments to pre-HoneyComb devices, if that makes any difference.

like image 699
Amit Avatar asked Mar 05 '13 07:03

Amit


People also ask

Which method is called when called to do final clean up of the fragment's state but not guaranteed to be called by the android platform?

onDestroy()onDestroy() called to do final clean up of the fragment's state but Not guaranteed to be called by the Android platform.

What is onActivityCreated in fragment?

onActivityCreated(Bundle) tells the fragment that its activity has completed its own Activity. onCreate() .

What is the difference between onCreate () and onCreateView () lifecycle methods in fragment?

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.

What the fragment's method setRetainInstance Boolean does?

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.


1 Answers

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 Fragments, 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.

like image 172
Nick Campion Avatar answered Sep 18 '22 12:09

Nick Campion