Nouvel Travay
Nouvel Travay

Reputation: 6472

Why is Fragment null inside onActivityResult

Here is my setup:

Activity -> FragmentWithPages -> ViewPager{Fragment1, Fragment2}

From Fragment1 I launch a DialogFragment and then from the DialogFragment I launch activityForResult for an implicit camera intent to take picture.

Problem:

Sometimes, when returning from the camera my app crashes inside the onActivityResult of Fragment1. Why does this happen? Now understand the chain of callback of onActivityResult. It would be coming back in the order of Activity.onActivityResult -> FragmentWithPages.onActivityResult -> Fragment1.onActivityResult -> DialogFragment.onActivityResult. So my question is, why is DialogFragment null when I do mDialogFragment.onActivityResult(…)?

I imagine it might have to do with memory: the system kills my app and then restarts it after the Camera app returns. But if that were the case, why is the DialogFragment the broken link in the chain? What can I do to prevent this problem or handle it as if nothing went wrong?

So no I do not mean to simply catch the NPE, that does not really do much as it would void the whole purpose for which I took the picture.

Upvotes: 2

Views: 855

Answers (2)

georgeok
georgeok

Reputation: 5716

This is a common situation where the system destroys your activity because it needs more resources. You need to implement the onSaveInstanceState method and then restore the instance state in the onCreate or onRestoreInstanceState method.

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putExtra("yourData", yourParcelableData);
}


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // keep the fragment and all its data across screen rotation
    setRetainInstance(true);
    if(savedInstanceState != null){
        yourParcelableData = (yourParcelableData)savedInstanceState.getExtra("yourData");
    }

}

There is a library that allows you to do it easier. https://github.com/frankiesardo/icepick

Upvotes: 1

Jeffrey Blattman
Jeffrey Blattman

Reputation: 22637

When you return from a startActivityForResult(), there's no guarantee that the activity instance will be the same. The system is free to dispose of the activity that started for result, and reconstruct it to handle the onActivityResult() call.

If this happens, it means of course that any instance fields you had previously assigned will no longer be so. It's up to you to use onSaveInstanceState() and reconstruct your activity instance using the saved instance state Bundle passed in to your onCreate().

You can test this scenario by setting "don't keep activities" in developer settings on your device.

Upvotes: 1

Related Questions