安卓。如何使用自定义 ArrayAdapter 和 ViewPagers 节省内存

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

所以我有一个带有 View Pager 的 MainActivity。我为 View Pager 创建了一个非静态自定义 FragmentPageAdapter,如下所示:

public class CustomViewPageAdapter extends FragmentStatePagerAdapter {

适配器有 4 个项目( fragment ),我将其声明为全局变量 MainActivity 为静态,例如:

    static HotFragment hotFragment;

然后我在 FragmentStatePagerAdapter 的 getItem() 方法中返回 hotFragment。

然后在我的 HotFragment 类中,我有另一个 ViewPager 以及另一个非静态的 FragmentStatePagerAdapter:在该适配器的 getItem() 方法中返回另一个名为 ImageDetailFragment 的 fragment 的新实例,如下所示:

return ImageDetailFragment.newInstance(arg0);

ImageDetailFragment 包含一个 ImageView,它将根据 arg0 的值保存不同的图像。该 ImageView 加载到 MainActivity 中的 AsyncTask 中。异步持有对 ImageView 的 WeakReference 以确保它被垃圾收集。

我的问题是: 当我滚动浏览图像时,我经常遇到 OutOfMemory 错误,尤其是当我退出 Activity 然后重新进入 Activity 时。我对内存管理和垃圾收集非常陌生,但我认为我在某处有内存泄漏。不,这不是一个模糊的问题。我想知道的是: 我是否应该将 hotFragment 设为静态,因为我知道静态对象会导致内存泄漏。 还。我的 FragmentStatePagerAdapters 是 nonStatic 这么糟糕。所有适配器都应该在 fragment 中是静态的。 另一件事。在我的 HotFragment 中 FragmentPagerAdapter 的 getItem(id) 方法中,我返回:

ImageDetailFragment.newInstance();

而不是在实际的 HotFragment 中创建 ImageDetailFragment 的实例。这很糟糕吗?因为在我的 MainActivity 中,我返回 hotFragment 的方式与在 MainActivity 中创建 hotFragment 的静态实例然后返回它的方式不同。哪个更好。

如果你们能帮助我,我将不胜感激。我是内存管理的新手,不确定避免内存泄漏的最佳做法是什么。如果我的问题太长或含糊不清,我很抱歉。我真的试着让它尽可能具有描述性......谢谢

最佳答案

如果你真的确定内存中有很多静态 fragment 会消耗大量内存,也许你可以尝试这样的事情:

而不是使用:

    @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);
    }

您实际上可以声明一个 fragment 映射。主要目标是重用以前创建的 fragment ,而不是继续声明新实例。首先,在 fragment 的 Activity 上声明此代码(不在 SectionsPagerAdapter 中):

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

然后将 SectionsPagerAdapter 中的 getItem(int position) 方法替换为:

    @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;
    }

我不知道是否有更好的方法,但我目前正在我的代码中使用它。

关于安卓。如何使用自定义 ArrayAdapter 和 ViewPagers 节省内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26664442/

相关文章:

java - 如何保持android客户端和套接字服务器之间的连接?

java - 如何通过按钮将 Activity 链接到 Fragment

python 内存泄漏、泄漏帧

java - 如何在 android studio 中将设定的字符串转换为语音?

android - 获取 EditTextPreference 值

java - android: TimeZone.getDefault() 返回 EST,而不是 EDT

android - 如何在没有黑屏的情况下处理android相机打开

java - 两个 fragment ,其中只有一个具有工具栏

.NET4 ExpandoObject 使用泄漏内存

java - RecyclerView 中的 MapView 内存泄漏