2

My code:

public class MainActivity extends AppCompatActivity {
    private FragmentA fragmentA;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (savedInstanceState == null) {
            fragmentA = FragmentA.newInstance();
            FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
            fragmentTransaction.replace(R.id.fragment_a_container, fragmentA, "FRAGMENT_A");
            fragmentTransaction.commit();
        }
        else {
            fragmentA = (FragmentA) getSupportFragmentManager().findFragmentByTag("FRAGMENT_A");
        }
    }

}

I don't really know what I am doing but this is currently what I do. I define a container for the Fragment and then I use a FragmentTransaction to replace it with a Fragment. The part I am confused about though is the else statement.

  1. Should I be structuring this differently?

  2. I thought configuration changes wiped out Activities and Fragments so why check for the Fragment in some support manager? Does this mean Fragments don't actually get destroyed? At the same time, they DO seem to get destroyed because they appear to reset unless I use onSaveInstanceState or the getArguments() approach.

Edit: What's wrong with doing this:

public class MainActivity extends AppCompatActivity {
    private FragmentA fragmentA;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        fragmentA = FragmentA.newInstance();
        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
        fragmentTransaction.replace(R.id.fragment_a_container, fragmentA, "FRAGMENT_A");
        fragmentTransaction.commit();
    }

}
KaliMa
  • 1,970
  • 6
  • 26
  • 51

1 Answers1

1

They do get destroyed and recreated for you on configuration changes by the, in this case, SupportFragmentManager.

To answer your questions:

  1. Should I be structuring this differently?

No, that's exactly how you should create fragments if there is no saved state and retrieve them when there is. See also my answer here;

  1. a) so why check for the Fragment in some support manager?

Because the manager handles the lifecyle of the fragment for you when there is a configuration change.

  1. b) Does this mean Fragments don't actually get destroyed?

No, it does get destroyed. See this diagram for a reference.

Edit to answer some of your questions from the comments:

But any member variables inside that Fragment are completely lost on configuration change unless I save them in that Fragment's onSaveInstanceState, right?

That is correct. Because your fragment is being destroyed, everything not being saved on onSaveInstanceState gets lost.

So then what exactly am I restoring?

You are not restoring anything. You are only retrieving the reference to the fragment that was previously created. You restore your variables on the onRestoreInstanceState() method of your fragment.

What's wrong with doing this (the code from the edit in the question)?

If you do that, you are adding a new fragment instance to the R.id.fragment_a_container container. So the old fragment will get lost together with the state of it you saved on onSaveInstanceState(). It will be a new fragment, with new information in it and the event onRestoreInstanceState() won't be called for it.

Community
  • 1
  • 1
Ricardo
  • 7,785
  • 8
  • 40
  • 60
  • I still don't understand. Is the line `fragmentA = (FragmentA) getSupportFragmentManager().findFragmentByTag("FRAGMENT_A");` correct? Or can I remove this and always call the code that's in the first code block? (the transaction code) – KaliMa Oct 07 '16 at 21:35
  • You need to keep it because that's how you retrieve the fragment you previously created. the "FRAGMENT_A" tag is what identifies your fragment with the manager. – Ricardo Oct 07 '16 at 21:36
  • But if I rotate the screen and it destroys the Activity and the Fragment, how can the Fragment still "exist" somewhere where I can re-associate it with my `fragmentA` member? – KaliMa Oct 07 '16 at 21:37
  • because the manager recreates it and re-associates it for you. – Ricardo Oct 07 '16 at 21:38
  • But any member variables inside that Fragment are completely lost on configuration change unless I save them in that Fragment's `onSaveInstanceState`, right? So then what exactly am I restoring? – KaliMa Oct 07 '16 at 21:39
  • But what about when using the newInstance() pattern, where the contents of the argument `Bundle` survive configuration changes? Do those Bundles "survive" and continue to be associated with the Fragment reference I am pulling out of the Fragment manager? – KaliMa Oct 07 '16 at 21:54
  • yes. you can always get them with the `getArguments()` method inside the fragment. You can try all this by yourself, by the way, by rotating the screen and seeing what happens. – Ricardo Oct 07 '16 at 21:56
  • I just didn't understand what it meant for the Fragment to be "destroyed" and yet at the same time something you can still "retrieve" in the else statement on an Activity's configuration change. Those two ideas seemed to be in direct contradiction to me, unless "destroy" has a very specific meaning. – KaliMa Oct 07 '16 at 21:57
  • it's destroyed and recreated. So you are retrieving the fragment that was recreated. – Ricardo Oct 07 '16 at 21:58
  • Oh, so when Fragments are recreated, they are recreated in the Fragment manager, and so that's all we're doing in the Activity, is re-establishing the link, otherwise we lose our saved instance state? What about when you use setRetainInstance()? Is that doing something different altogether? – KaliMa Oct 07 '16 at 22:03
  • if you use `setRetainInstance()` the fragment doesn't get destroyed and recreated so you don't need to worry about saving the contents of your variables on `onSaveInstanceState()`. But you still need to use `findFragmentByTag()` to retrieve the reference to that fragment instead of creating a new one. – Ricardo Oct 08 '16 at 07:51
  • Any reason to use one saving approach over the other? What do you use? – KaliMa Oct 08 '16 at 15:29