XWang
XWang

Reputation: 797

How to reduce the memory usage when using fragment with back stack?

I'm developing a social app with several fragments. There is one Friend fragment which contains a grid view. If I click one item, then opens a Profile fragment, and add it into back stack. Then in the Profile fragment, the user can still enter a new Friend fragment, and add it into the back stack, etc. So the back stack could be Friend a -> Profile b -> Friend c -> Profile d -> Friend e -> Profile f -> ...

So my question is, since the user can enter several levels, and put several fragments into the back stack, and some of the fragment has a lot of image views, how to reduce the memory usage and avoid OOE?

Thanks in advance.

Upvotes: 2

Views: 2192

Answers (2)

user2487700
user2487700

Reputation: 11

This is a classic problem with social media apps. If you look at many of the commercial social media apps you will be able to crash them going through the process you mention. Some thoughts on managing the memory is to always check the memory usage as you add fragments. And when you hit a certain limit then either decide to thrash the previous fragments or warn the user. One of the biggest issues is related to what is in each fragment as the user delves further down. If you have many images loading in each fragment (which is usually the case with social media) then you might consider thrashing out the images held in the fragments as the user navigates further in. When they come back using the back button, the fragment will then reload the images from the server. So its a combination of both limiting the sheer number of fragments as well as the content inside the fragments as they go on the stack.

Also remember, as you use the back button to navigate backwards, the stack pop will not remove the fragment from memory. You also have to explicitly call remove and then do a GC to ensure things get removed as you back track.

Here I have an example of a HashMap Stack to hold fragments associated with a Tab. Something like this,

    private void popFragments(){

    if(mStacks.get(currentTab)!=null && mStacks.get(currentTab).size()>1){ 

        FragmentManager fm = getSupportFragmentManager();
        Fragment currentFrag=mStacks.get(currentTab).pop();

            // This is the part that will reclaim the memory
        if(currentFrag.isAdded()){
            fm.beginTransaction().detach(currentFrag).commit();
            fm.beginTransaction().remove(currentFrag).commit();
        }
        currentFrag=null;
        System.gc();
        Fragment newFrag=mStacks.get(currentTab).lastElement();
        if(newFrag !=null && newFrag.isAdded()){
            fm.beginTransaction().attach(newFrag).commit();
        }
        else if(newFrag !=null && !newFrag.isAdded()){
            fm.beginTransaction().add(R.id.fragment_content, newFrag,newFrag.getTag()).commit();
            fm.beginTransaction().attach(newFrag).commit();
        }
        actionbar.setLargeTitle(newFrag.getTag()); 
    }
}

Good luck.

Upvotes: 1

RAW
RAW

Reputation: 7825

Your probably only have one real way - to limit the back stack! Here's a post how you can do this: How to limit the number of the same Activity on the stack for an Android application

Best Regards

safari

PS: Also take a look here: http://developer.android.com/guide/components/tasks-and-back-stack.html


Look here, thats what you need to do:

FragmentManager fm = getActivity().getSupportFragmentManager();
for(int i = 0; i < fm.getBackStackEntryCount(); ++i) {    
    fm.popBackStack();
}

Also you could use something like this:

FragmentManager.popBackStack(String name, FragmentManager.POP_BACK_STACK_INCLUSIVE)

Hope this helps.

Best Regards

Upvotes: 2

Related Questions