简体   繁体   中英

Why is DialogFragment.onCreateView called when Activity is being Destroyed?

I'm using the android support library v4 revision 11 and time to time, I see the stack trace below ; I suspect it's happening due to a launch from recents, hence the model I'm trying to access is null. Anyhow, this trace has made me wonder why onCreateView is called when the activity is being destroyed, and what's the best way to handle such cases?

java.lang.NullPointerException
    at com.example.dialogs.ExampleDialogFragment.onCreateView(ExampleDialogFragment.java:53)
    at android.support.v4.app.Fragment.performCreateView(Fragment.java:1460)
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:911)
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1088)
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1070)
    at android.support.v4.app.FragmentManagerImpl.dispatchReallyStop(FragmentManager.java:1888)
    at android.support.v4.app.FragmentActivity.onReallyStop(FragmentActivity.java:787)
    at android.support.v4.app.FragmentActivity.doReallyStop(FragmentActivity.java:764)
    at android.support.v4.app.FragmentActivity.onDestroy(FragmentActivity.java:322)
    at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3642)
    at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3673)
    at android.app.ActivityThread.access$2900(ActivityThread.java:125)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:123)
    at android.app.ActivityThread.main(ActivityThread.java:4627)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:521)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
    at dalvik.system.NativeStart.main(Native Method)

After the crash an activity from back-stack is resumed, I do check if the model is valid at activities onResume() , onStart() and onCreate(Bundle savedInstanceState) . If the model is not valid I start another activity from there with FLAG_ACTIVITY_NO_HISTORY , call finish() and return; eg

@Override
public void onResume() {        
    Model cm = Application.getModel();
    final boolean isModelAvailable = cm != null;
    if (!isModelAvailable) {
        Intent restartIntent = IntentUtil.intentForAction(Constants.INTENT_RESTART);
        restartIntent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
        startActivity(restartIntent);
        finish();
        super.onResume();
        return;
    } else {

    }

after INTENT_RESTART activity is finished with reinitializing the model it starts activity with flags FLAG_ACTIVITY_CLEAR_TOP , this activity commits transaction to the fragment FirstFragment

See the log with FragmentManager.enableDebugLogging(true); .

05-13 13:24:53.051: V/FragmentManager(7468): Commit: BackStackEntry{40710fa0}
05-13 13:24:53.111: V/FragmentManager(7468): Commit: BackStackEntry{40771e78}
05-13 13:24:53.151: V/FragmentManager(7468): Run: BackStackEntry{40710fa0}
05-13 13:24:53.151: V/FragmentManager(7468): add: RetainFragment{4077d048 app_ImageCache}
05-13 13:24:53.151: V/FragmentManager(7468): Allocated fragment index RetainFragment{4077d048 #0 app_ImageCache}
05-13 13:24:53.151: V/FragmentManager(7468): moveto CREATED: RetainFragment{4077d048 #0 app_ImageCache}
05-13 13:24:53.151: V/FragmentManager(7468): moveto ACTIVITY_CREATED: RetainFragment{4077d048 #0 app_ImageCache}
05-13 13:24:53.151: V/FragmentManager(7468): Run: BackStackEntry{40771e78}
05-13 13:24:53.151: V/FragmentManager(7468): add: FirstFragment{4077dfa8 id=0x7f04000d}
05-13 13:24:53.151: V/FragmentManager(7468): Allocated fragment index FirstFragment{4077dfa8 #1 id=0x7f04000d}
05-13 13:24:53.151: V/FragmentManager(7468): moveto CREATED: FirstFragment{4077dfa8 #1 id=0x7f04000d}
05-13 13:24:53.151: V/FragmentManager(7468): moveto ACTIVITY_CREATED: FirstFragment{4077dfa8 #1 id=0x7f04000d}
05-13 13:24:53.791: V/FragmentManager(7468): moveto STARTED: RetainFragment{4077d048 #0 app_ImageCache}
05-13 13:24:53.791: V/FragmentManager(7468): moveto STARTED: FirstFragment{4077dfa8 #1 id=0x7f04000d}
05-13 13:24:53.811: V/FragmentManager(7468): moveto RESUMED: RetainFragment{4077d048 #0 app_ImageCache}
05-13 13:24:53.811: V/FragmentManager(7468): moveto RESUMED: FirstFragment{4077dfa8 #1 id=0x7f04000d}

05-13 13:25:58.414: V/FragmentManager(7468): Commit: BackStackEntry{40727530}
05-13 13:25:58.434: V/FragmentManager(7468): Run: BackStackEntry{4078fe00}
05-13 13:25:58.434: V/FragmentManager(7468): add: RetainFragment{4076f1b0 app_ImageCache}
05-13 13:25:58.434: V/FragmentManager(7468): Allocated fragment index RetainFragment{4076f1b0 #0 app_ImageCache}
05-13 13:25:58.434: V/FragmentManager(7468): moveto CREATED: RetainFragment{4076f1b0 #0 app_ImageCache}
05-13 13:25:58.434: V/FragmentManager(7468): moveto ACTIVITY_CREATED: RetainFragment{4076f1b0 #0 app_ImageCache}
05-13 13:25:58.434: V/FragmentManager(7468): Run: BackStackEntry{40727530}
05-13 13:25:58.434: V/FragmentManager(7468): add: SecondFragment{40713c28 id=0x7f04000d}
05-13 13:25:58.434: V/FragmentManager(7468): Allocated fragment index SecondFragment{40713c28 #1 id=0x7f04000d}
05-13 13:25:58.434: V/FragmentManager(7468): moveto CREATED: SecondFragment{40713c28 #1 id=0x7f04000d}
05-13 13:25:58.434: V/FragmentManager(7468): moveto ACTIVITY_CREATED: SecondFragment{40713c28 #1 id=0x7f04000d}
05-13 13:25:58.545: V/FragmentManager(7468): moveto STARTED: RetainFragment{4076f1b0 #0 app_ImageCache}
05-13 13:25:58.545: V/FragmentManager(7468): moveto STARTED: SecondFragment{40713c28 #1 id=0x7f04000d}
05-13 13:25:58.565: V/FragmentManager(7468): moveto RESUMED: RetainFragment{4076f1b0 #0 app_ImageCache}
05-13 13:25:58.565: V/FragmentManager(7468): moveto RESUMED: SecondFragment{40713c28 #1 id=0x7f04000d}

05-13 13:26:02.338: V/FragmentManager(7468): Saved state of RetainFragment{4077d048 #0 app_ImageCache}: null
05-13 13:26:02.338: V/FragmentManager(7468): Saved state of FirstFragment{4077dfa8 #1 id=0x7f04000d}: Bundle[{android:view_state=android.util.SparseArray@40b15b60}]
05-13 13:26:02.338: V/FragmentManager(7468): saveAllState: adding fragment #0: RetainFragment{4077d048 #0 app_ImageCache}
05-13 13:26:02.338: V/FragmentManager(7468): saveAllState: adding fragment #1: FirstFragment{4077dfa8 #1 id=0x7f04000d}
05-13 13:26:02.348: V/FragmentManager(7468): movefrom STARTED: RetainFragment{4077d048 #0 app_ImageCache}
05-13 13:26:02.348: V/FragmentManager(7468): movefrom STARTED: FirstFragment{4077dfa8 #1 id=0x7f04000d}
05-13 13:26:02.358: V/FragmentManager(7468): movefrom STOPPED: RetainFragment{4077d048 #0 app_ImageCache}
05-13 13:26:02.358: V/FragmentManager(7468): movefrom STOPPED: FirstFragment{4077dfa8 #1 id=0x7f04000d}
05-13 13:27:15.219: V/FragmentManager(7468): movefrom RESUMED: RetainFragment{4076f1b0 #0 app_ImageCache}
05-13 13:27:15.219: V/FragmentManager(7468): movefrom RESUMED: SecondFragment{40713c28 #1 id=0x7f04000d}

05-13 13:27:15.239: V/FragmentManager(7468): Commit: BackStackEntry{40a8a6d0}
05-13 13:27:15.259: V/FragmentManager(7468): Commit: BackStackEntry{40a90190}

05-13 13:27:15.279: V/FragmentManager(7468): Run: BackStackEntry{40a8a6d0}
05-13 13:27:15.279: V/FragmentManager(7468): add: RetainFragment{40a7fdf0 app_ImageCache}
05-13 13:27:15.279: V/FragmentManager(7468): Allocated fragment index RetainFragment{40a7fdf0 #0 app_ImageCache}
05-13 13:27:15.279: V/FragmentManager(7468): moveto CREATED: RetainFragment{40a7fdf0 #0 app_ImageCache}
05-13 13:27:15.279: V/FragmentManager(7468): moveto ACTIVITY_CREATED: RetainFragment{40a7fdf0 #0 app_ImageCache}
05-13 13:27:15.279: V/FragmentManager(7468): Run: BackStackEntry{40a90190}
05-13 13:27:15.279: V/FragmentManager(7468): add: ThirdFragment{406c2308 id=0x7f04000d}
05-13 13:27:15.279: V/FragmentManager(7468): Allocated fragment index ThirdFragment{406c2308 #1 id=0x7f04000d}
05-13 13:27:15.289: V/FragmentManager(7468): moveto CREATED: ThirdFragment{406c2308 #1 id=0x7f04000d}
05-13 13:27:15.289: V/FragmentManager(7468): moveto ACTIVITY_CREATED: ThirdFragment{406c2308 #1 id=0x7f04000d}
05-13 13:27:15.410: V/FragmentManager(7468): moveto STARTED: RetainFragment{40a7fdf0 #0 app_ImageCache}
05-13 13:27:15.410: V/FragmentManager(7468): moveto STARTED: ThirdFragment{406c2308 #1 id=0x7f04000d}
05-13 13:27:15.430: V/FragmentManager(7468): moveto RESUMED: RetainFragment{40a7fdf0 #0 app_ImageCache}
05-13 13:27:15.430: V/FragmentManager(7468): moveto RESUMED: ThirdFragment{406c2308 #1 id=0x7f04000d}
05-13 13:27:15.810: V/FragmentManager(7468): Saved state of RetainFragment{4076f1b0 #0 app_ImageCache}: null
05-13 13:27:15.810: V/FragmentManager(7468): Saved state of SecondFragment{40713c28 #1 id=0x7f04000d}: Bundle[{android:view_state=android.util.SparseArray@40aa62c0}]
05-13 13:27:15.810: V/FragmentManager(7468): saveAllState: adding fragment #0: RetainFragment{4076f1b0 #0 app_ImageCache}
05-13 13:27:15.810: V/FragmentManager(7468): saveAllState: adding fragment #1: SecondFragment{40713c28 #1 id=0x7f04000d}
05-13 13:27:15.810: V/FragmentManager(7468): movefrom STARTED: RetainFragment{4076f1b0 #0 app_ImageCache}
05-13 13:27:15.810: V/FragmentManager(7468): movefrom STARTED: SecondFragment{40713c28 #1 id=0x7f04000d}
05-13 13:27:15.820: V/FragmentManager(7468): movefrom STOPPED: RetainFragment{4076f1b0 #0 app_ImageCache}
05-13 13:27:15.820: V/FragmentManager(7468): movefrom STOPPED: SecondFragment{40713c28 #1 id=0x7f04000d}


// Here I'm waiting for a while to make sure Android has enough time to do anything it wants, then I press a button gorse-closing the app  
05-13 13:27:59.783: D/AndroidRuntime(7468): Shutting down VM


05-13 13:28:14.928: V/FragmentManager(7523): Instantiated fragment RetainFragment{406cde80 #0 app_ImageCache}
05-13 13:28:14.938: V/FragmentManager(7523): restoreAllState: active #0: RetainFragment{406cde80 #0 app_ImageCache}
05-13 13:28:14.938: V/FragmentManager(7523): Instantiated fragment FirstFragment{406d8410 #1 id=0x7f04000d}
05-13 13:28:14.938: V/FragmentManager(7523): restoreAllState: active #1: FirstFragment{406d8410 #1 id=0x7f04000d}
05-13 13:28:14.938: V/FragmentManager(7523): restoreAllState: added #0: RetainFragment{406cde80 #0 app_ImageCache}
05-13 13:28:14.938: V/FragmentManager(7523): restoreAllState: added #1: FirstFragment{406d8410 #1 id=0x7f04000d}
05-13 13:28:14.938: V/FragmentManager(7523): moveto CREATED: RetainFragment{406cde80 #0 app_ImageCache}
05-13 13:28:14.938: V/FragmentManager(7523): moveto CREATED: FirstFragment{406d8410 #1 id=0x7f04000d}

05-13 13:28:15.128: V/msm8660.gralloc(7523): PmemUserspaceAllocator::PmemUserspaceAllocator(PmemUserspaceAllocator::Deps&, PmemUserspaceAllocator::Deps::Allocator&, const char*) begin
05-13 13:28:15.138: V/msm8660.gralloc(7523): PmemUserspaceAllocator::PmemUserspaceAllocator(PmemUserspaceAllocator::Deps&, PmemUserspaceAllocator::Deps::Allocator&, const char*) end
05-13 13:28:15.138: V/msm8660.gralloc(7523): PmemKernelAllocator::PmemKernelAllocator(PmemKernelAllocator::Deps&) begin
05-13 13:28:15.138: V/msm8660.gralloc(7523): PmemKernelAllocator::PmemKernelAllocator(PmemKernelAllocator::Deps&) end

05-13 13:28:15.408: V/FragmentManager(7523): moveto ACTIVITY_CREATED: RetainFragment{406cde80 #0 app_ImageCache}
05-13 13:28:15.408: V/FragmentManager(7523): moveto ACTIVITY_CREATED: FirstFragment{406d8410 #1 id=0x7f04000d}

java.lang.RuntimeException: Unable to destroy activity {com.myapp/com.myapp.activity.FirstFragment}: java.lang.NullPointerException

05-13 13:35:41.824: E/AndroidRuntime(7691):     at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3272)
05-13 13:35:41.824: E/AndroidRuntime(7691):     at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3299)
05-13 13:35:41.824: E/AndroidRuntime(7691):     at android.app.ActivityThread.access$2100(ActivityThread.java:134)
05-13 13:35:41.824: E/AndroidRuntime(7691):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1143)
05-13 13:35:41.824: E/AndroidRuntime(7691):     at android.os.Handler.dispatchMessage(Handler.java:99)
05-13 13:35:41.824: E/AndroidRuntime(7691):     at android.os.Looper.loop(Looper.java:152)
05-13 13:35:41.824: E/AndroidRuntime(7691):     at android.app.ActivityThread.main(ActivityThread.java:4606)
05-13 13:35:41.824: E/AndroidRuntime(7691):     at java.lang.reflect.Method.invokeNative(Native Method)
05-13 13:35:41.824: E/AndroidRuntime(7691):     at java.lang.reflect.Method.invoke(Method.java:491)
05-13 13:35:41.824: E/AndroidRuntime(7691):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
05-13 13:35:41.824: E/AndroidRuntime(7691):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
05-13 13:35:41.824: E/AndroidRuntime(7691):     at dalvik.system.NativeStart.main(Native Method)

// see the original question log, it is quite the same
05-13 13:35:41.824: E/AndroidRuntime(7691): Caused by: java.lang.NullPointerException
05-13 13:35:41.824: E/AndroidRuntime(7691):     at com.myapp/com.myapp.activity.FirstFragment.onCreateView(FirstFragment.java:41)
05-13 13:35:41.824: E/AndroidRuntime(7691):     at android.support.v4.app.Fragment.performCreateView(Fragment.java:1460)
05-13 13:35:41.824: E/AndroidRuntime(7691):     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:911)
05-13 13:35:41.824: E/AndroidRuntime(7691):     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1088)
05-13 13:35:41.824: E/AndroidRuntime(7691):     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1070)
05-13 13:35:41.824: E/AndroidRuntime(7691):     at android.support.v4.app.FragmentManagerImpl.dispatchReallyStop(FragmentManager.java:1888)
05-13 13:35:41.824: E/AndroidRuntime(7691):     at android.support.v4.app.FragmentActivity.onReallyStop(FragmentActivity.java:787)
05-13 13:35:41.824: E/AndroidRuntime(7691):     at android.support.v4.app.FragmentActivity.doReallyStop(FragmentActivity.java:764)
05-13 13:35:41.824: E/AndroidRuntime(7691):     at android.support.v4.app.FragmentActivity.onDestroy(FragmentActivity.java:322)
05-13 13:35:41.824: E/AndroidRuntime(7691):     at com.myapp.activity.FragmentsContainerActivity.onDestroy(FragmentsContainerActivity.java:806)
05-13 13:35:41.824: E/AndroidRuntime(7691):     at android.app.Activity.performDestroy(Activity.java:4662)
05-13 13:35:41.824: E/AndroidRuntime(7691):     at android.app.Instrumentation.callActivityOnDestroy(Instrumentation.java:1113)
05-13 13:35:41.824: E/AndroidRuntime(7691):     at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3255)
05-13 13:35:41.824: E/AndroidRuntime(7691):     ... 11 more

The line #806 of FragmentsContainerActivity is super.onDestroy(); :

@Override
public void onDestroy() {
    try {
        unregister(receiver);
    } catch (Exception e) {
    }
    super.onDestroy();

As guided in the code sample here referring to the onResume method You should:

Always call the superclass method first

Meanning you should put your super.onResume(); right at the start. That must be the problem.

At the current code you are running, you are confusing the FragmentActivity who is being told to stop (ie finish ) and then being told to resume . a life cycle which is not "legit" in the activity life cycle. The fragments are affected directly by that because their life cycle is invoked from the activity life cycle, and if the activity went from finishing -> resume it can sure mean that the fragments went from finishing/destroy -> resuming (going through onCreateView) .

Without seeing the code, we can't help you with the specific problem at hand. For one, though, the fact that it's a DialogFragment is irrelevant.

That said, in my experience, FragmentManager.enableDebugLogging() is a life-saver when you're having trouble with the lifecycles. It would, for example, tell you what that last moveToState does (ie, what states it's moving between), which might shed some light on the bug.

For your specific problem did you try calling the super.resume() before calling finish() ?

Otherwise you should look at the source code: https://github.com/mastro/android-support-library-archive/blob/23ad71b245e7b7bbde6a501671ab411725ce16f5/v4/src/java/android/support/v4/app/FragmentManager.java

From this stacktrace line android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:911)

Please see this similar question, which describes the same behavior that you're seeing, but the solution probably doesn't apply in your case. To fix your issue, you could simply check if anything that your code is relying on in onCreateView is null .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM