Android maintain Fragment State

In this post I would like to focus on one unclear issue during the Android development.

Every body who has worked with Fragment object in Android and he spend at least 1-2 hours to understand how those objects work, he will know that onCreateView() of the Fragment object is called when the fragment is showing for the first time and also when the fragment is resume when user press back button and return to it from previous screen (does not matter Activity or Fragment).

So this point is a little bit sensitive and if you want to have good performance in your app you have to manage it very well. There have 3 base opinions about,  which way is the right way. I will put here them and at the end I will leave my comment about this issue.

  1. Use onSaveInstanceState() in Fragment object to handle the fragment state.
  2. Create instance inside your Fragment of the rootview and keep it until this Fragment is live;
  3. Leave Fragment object to recreate its views by it self every time when it is created/returned from the activity back stack in onCreateView() method;

Well I think the the most right way is the 3-th one and I am applying it in all my fragments.

The second decision is also fine and easy but it have one big problem, when you have to use more then 2-3 instances of your fragments this will consume a lot of memory and the GC will not release this unnecessary objects. Look at this code:

public class SomeFragment extends Fragment {
    View rootView;
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        if (rootView == null) {
            rootView = inflater.inflate(R.layout.fragment_a, container, false);
            // Setup subviews
        } else {
            // Do not inflate the layout again.
            // The returned View of onCreateView will be added into the fragment.
            // However it is not allowed to be added twice even if the parent is same.
            // So we must remove _rootView from the existing parent view group
            // (it will be added back).
            ((ViewGroup)rootView.getParent()).removeView(rootView);
        }
        return rootView;
    }
}

It seems that you will create only ones your views (inflate) and after that you will miss that part, easy but it will cost problems with the memory for future. You can use this method only if your app has 2-3 screens in one Activity and it doesn’t need more memory and more screens, but if you need then DON’T DO IT.

And the end of this talk I will finally say my solution about the issue:

Leave your Fragment to recreate it’s views  every time when it create it self for the first time or return from the activity back stack. Keep references to your data (Lists) or save them state on the Fragment  onSaveInstanceState() and after that reuse only the data.

Note: Every time when you recreate your views you need to load all fragment data to the new views (they will have new references in the memory, they will be totally new objects), because for example if you have Adapter attached to the RecyclerView, and you recreate your recycler view, the new recycler view need to be associated with this old adapter object. You don’t need to recreate your data list and attached to the adapter ,it is already  there. You just need to tell to the news recyclerview that it’s adapter is the old adapter, otherwise you will see empty recyclerview object without any dat in it.

I hope this explanation  will be useful to somebody and the issue will be clear for all of us.

Leave a Reply

Your email address will not be published. Required fields are marked *