片段内存管理

时间:2015-07-30 15:50:01

标签: android android-fragments android-viewpager out-of-memory

我正在构建一个包含大量片段的应用程序,但我有一些内存问题。

第一个似乎在我的viewpager中。我正在使用一个fragmentStatePagerAdapter,因为它中可能有很多片段(因此,如果我是正确的话,只应在内存中保留少量片段)。 其中有一个滚动视图,我在每个片段中滚动一下进行测试。我想如果我在左边的5个片段中我会稍微晃动一下然后我回到原来的片段,卷轴应该重置,因为它们不应该保留在内存中,但它是。

以下是我的viewpager的代码:

public class MonoArticlePagerFragment extends Fragment{
    private static final String IS_NEW_FRAG = "IS_NEW_FRAG";
    private static final String POSITION = "POSITION";
    private ViewPager mPager;
    private ArticlePagerAdapter mPagerAdapter;
    private boolean mIsNewFragment;
    private int mPosition;

    public static MonoArticlePagerFragment newInstance(boolean isNewFragment, int position) {

        Bundle args = new Bundle();
        args.putBoolean(IS_NEW_FRAG, isNewFragment);
        args.putInt(POSITION, position);
        MonoArticlePagerFragment fragment = new MonoArticlePagerFragment();
        fragment.setArguments(args);
        return fragment;
    }


    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Bundle args = getArguments();
        mIsNewFragment = args.getBoolean(IS_NEW_FRAG);
        mPosition = args.getInt(POSITION);
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = View.inflate(getActivity(), R.layout.fragment_current_articles_pager,null);

        mPager = (ViewPager) rootView.findViewById(R.id.pager);
        mPagerAdapter = new ArticlePagerAdapter(getActivity().getSupportFragmentManager(), CurrentArticlesFragment.sListArticles);
        mPager.setAdapter(mPagerAdapter);
//        mPager.setOffscreenPageLimit(1);
        if (!mIsNewFragment) {
            mPager.setCurrentItem(mPosition);
        } else {
            mPager.setCurrentItem(CurrentArticlesFragment.sListArticles.size() - 1);
        }
        return rootView;
    }
}

MonoArticleFragment类:

public class MonoArticleFragment extends Fragment {

    private static final String LOG_TAG = "MonoArticleFragment";
    private View mPhotos;
    private View mGeneral;
    private View mSourcing;
    private View mNavision;
    private View mStatistiques;
    private View mDescriptions;
    private ScrollView mScrollView;


    public static MonoArticleFragment newInstance() {

        Bundle args = new Bundle();

        MonoArticleFragment fragment = new MonoArticleFragment();
        fragment.setArguments(args);
        return fragment;
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_current_articles_mono, container,false);
        View.OnClickListener listener = new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int id = v.getId();
                if (id == R.id.mono_article_tab_btn_statistiques) {
                    mScrollView.smoothScrollTo(0,mStatistiques.getTop());
                } else if (id == R.id.mono_article_tab_btn_sourcing) {
                    mScrollView.smoothScrollTo(0,mSourcing.getTop());
                } else if (id == R.id.mono_article_tab_btn_photos) {
                    mScrollView.smoothScrollTo(0,mPhotos.getTop());
                } else if (id == R.id.mono_article_tab_btn_navision) {
                    mScrollView.smoothScrollTo(0,mNavision.getTop());
                } else if (id == R.id.mono_article_tab_btn_general) {
                    mScrollView.smoothScrollTo(0,mGeneral.getTop());
                } else if (id == R.id.mono_article_tab_btn_descriptions) {
                    mScrollView.smoothScrollTo(0,mDescriptions.getTop());
                }
            }
        };
        mScrollView = (ScrollView) rootView.findViewById(R.id.fragment_current_articles_mono_scrollview);

        rootView.findViewById(R.id.mono_article_tab_btn_descriptions).setOnClickListener(listener);
        rootView.findViewById(R.id.mono_article_tab_btn_general).setOnClickListener(listener);
        rootView.findViewById(R.id.mono_article_tab_btn_navision).setOnClickListener(listener);
        rootView.findViewById(R.id.mono_article_tab_btn_photos).setOnClickListener(listener);
        rootView.findViewById(R.id.mono_article_tab_btn_sourcing).setOnClickListener(listener);
        rootView.findViewById(R.id.mono_article_tab_btn_statistiques).setOnClickListener(listener);

//        mPhotos = rootView.findViewById(R.id.fragment_current_articles_mono_photos_anchor);
        mGeneral = rootView.findViewById(R.id.fragment_current_articles_mono_general_anchor);
        mSourcing = rootView.findViewById(R.id.fragment_current_articles_mono_sourcing_anchor);
        mNavision = rootView.findViewById(R.id.fragment_current_articles_mono_navision_anchor);
        mStatistiques = rootView.findViewById(R.id.fragment_current_articles_mono_statistiques_anchor);
//        mDescriptions = rootView.findViewById(R.id.fragment_current_articles_mono_descriptions);

        return rootView;
    }

我不会发布XML文件,因为它很大。有一些带有TextInputLayout的EditText,TextView,View(用于制作分隔符),我主要使用LinearLayout来格式化它。我也有一些TableLayout。没有ImageView。

我的第二个问题也在于viewpager:我有一个方法用另一个片段替换它,以及用viewpager替换新片段的方法。我不想保存每个片段的状态(包含viewpager的片段包含其他片段,另一个片段包含recyclerview)。我总是调用supportFragmentManager的replace方法,但内存越来越大,直到我得到一个OutOfMemoryException

我用ListArticleFragment替换了上面包含的MonoArticlePagerFragment,它只包含一个没有图片的RecyclerView。

public class ListArticleFragment extends Fragment{

    private RecyclerView mRecyclerView;

    public static ListArticleFragment newInstance() {

        Bundle args = new Bundle();

        ListArticleFragment fragment = new ListArticleFragment();
        fragment.setArguments(args);
        return fragment;
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = View.inflate(getActivity(), R.layout.fragment_current_articles_list, null);
        mRecyclerView = (RecyclerView) rootView.findViewById(R.id.fragment_current_articles_list_recylcerview);
        GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(),5);
        mRecyclerView.setLayoutManager(gridLayoutManager);
        mRecyclerView.setAdapter(new ArticleListAdapter(getActivity(),CurrentArticlesFragment.sListArticles));
        return rootView;
    }
}

我用这个替换了这个片段:

mActivity.getSupportFragmentManager().beginTransaction()
            .replace(R.id.content, ListArticleFragment.newInstance())
            .commit();

由于我替换了MonoArticlePagerFragment,我希望他所占用的内存及其包含的片段是免费的,但它似乎并不像那样。 当我切换到MonoArticlePagerFragment(一个全新的实例,不需要维护状态或任何东西)时,我使用这个:

Fragment fragment = MonoArticlePagerFragment.newInstance(mIsNewFragment, mPosition);
mActivity.getSupportFragmentManager().beginTransaction()
        .replace(R.id.content, fragment)
        .commit();

为什么我的viewpager会保持滚动状态(我估计内存中的片段)以及为什么在第二种情况下会出现OutOfMemoryException?

0 个答案:

没有答案