android. How to conserve memory with custom ArrayA

2019-05-30 10:44发布

问题:

So I have a MainActivity with a View Pager. I create a nonstatic custom FragmentPageAdapter for the View Pager like this:

public class CustomViewPageAdapter extends FragmentStatePagerAdapter {

The Adapter has 4 items(fragments) Which I declare as global variables MainActivity as static so for example:

    static HotFragment hotFragment;

Then I return hotFragment in my getItem() method of the FragmentStatePagerAdapter.

Then in my HotFragment class I have another ViewPager as well as another FragmentStatePagerAdapter which is ALSO nonstatic: In the getItem() method of that Adapter return a new instance of another fragment called ImageDetailFragment like this:

return ImageDetailFragment.newInstance(arg0);

That ImageDetailFragment contatins an ImageView that will hold a different image depending on the value of arg0. That ImageView is loaded in an AsyncTask which is in the MainActivity. The async holds a WeakReference to the ImageView to ensure that it is Garbage collected.

My Problem is: I am often getting and OutOfMemory error when I scroll through the images, especially when I exit the activity and then re enter the activity. I am very new to memory management and garbage collection but I think I have a memory leak somewhere. No this isn't a vague question however. What I want to know is: Should I make my hotFragment static or not because I know static objects can cause memory leaks. Also. My FragmentStatePagerAdapters are nonStatic is this bad. Should all Adapters be static in fragments. Another thing. In my getItem(id) method in the FragmentPagerAdapter in my HotFragment I return:

ImageDetailFragment.newInstance();

instead of creating an instance of ImageDetailFragment in the actual HotFragment. Is this bad? Because in my MainActivity I don't return the hotFragment the same way I create a static instance of the hotFragment in the MainActivity then return that. Which one is better.

I would really appreciate it if you guys helped me. I am new to memory management and am unsure about what are the best practices to avoid memory leaks. I'm sorry if my question is too long or vague. I really tried to make it as descriptive as possible... Thank you

回答1:

If you are really sure that having lots of static fragments in memory consumes a huge amount of memory, maybe you could try something like this:

Instead of using:

    @Override
    public Fragment getItem(int position) {
        // getItem is called to instantiate the fragment for the given page.
        // Return a PlaceholderFragment (defined as a static inner class below).
        return PlaceholderFragment.newInstance(position);
    }

You could actually declare a Map of fragment. The main goal is to re-use previously created fragments, than keep declaring new instance. Firstly, declare this code on fragment's activity (NOT in SectionsPagerAdapter):

private Map<Integer, PlaceholderFragment> mPlaceHolderFragmentArray = new LinkedHashMap<Integer, PlaceholderFragment>(); 

Then replace getItem(int position) method in SectionsPagerAdapter with this:

    @Override
    public Fragment getItem(int position) {
        // getItem is called to instantiate the fragment for the given page.
        // Return a PlaceholderFragment (defined as a static inner class below).
        PlaceholderFragment fragment = mPlaceHolderFragmentArray.get(position);
        if(fragment == null){
            fragment = PlaceholderFragment.newInstance(position);
            mPlaceHolderFragmentArray.put(position, fragment);
        }
        return fragment;
    }

I don't know if there are any better way, but I'm currently using this on my codes.