2

我正在调查我们应用程序中的内存不足错误报告。

我们的应用程序显示了一个列表视图,其中应用程序图标作为列表视图项的一部分。

当使用标准 baseadapter 填充此列表视图时,可以观察到当包含它们的视图消失时,应用程序不会保留可绘制对象。

这也使用弱引用进行了测试:

 public Drawable getIcon() {
        Log.v("AppResult", "getIcon()");
        Drawable icon = appInfo.loadIcon(pm);       
        leakTester.add(new WeakReference<Drawable>(icon));
        ArrayList<WeakReference<Drawable>> copy = new ArrayList<WeakReference<Drawable>>(leakTester); 
        for (WeakReference<Drawable> oldIcon: leakTester)
        {
            if (oldIcon.get() == null)
            {
                Log.v("AppResult", "iconRecycled");
                copy.remove(oldIcon);
            }
        }
        leakTester = copy;
        return icon;
    }

滚动浏览正常的 baseadapter 驱动的列表视图时记录:

12-05 16:17:57.450: V/AppResult(24890): getIcon()
12-05 16:17:57.450: V/AppResult(24890): iconRecycled
12-05 16:17:57.510: V/AppResult(24890): getIcon()
12-05 16:17:57.520: V/AppResult(24890): iconRecycled
12-05 16:17:57.580: V/AppResult(24890): getIcon()
12-05 16:17:57.590: V/AppResult(24890): iconRecycled
12-05 16:17:57.730: V/AppResult(24890): getIcon()
12-05 16:17:57.730: V/AppResult(24890): iconRecycled
12-05 16:17:58.510: V/AppResult(24890): getIcon()
12-05 16:17:58.510: V/AppResult(24890): iconRecycled
12-05 16:17:58.570: V/AppResult(24890): getIcon()
12-05 16:17:58.570: V/AppResult(24890): iconRecycled
12-05 16:17:58.650: V/AppResult(24890): getIcon()

然而,当我使用一个合并适配器时,它充满了交替的标题文本视图和基础适配器,就像之前使用的那样,我收到的消息很少 iconRecycled。即使这些适配器在可用时确实使用了回收视图。(该应用程序的使用量达到 35MB!在滚动完整列表后,它在其他活动中保持在 12MB)。

12-05 16:15:04.800: V/AppResult(24890): getIcon()
12-05 16:15:04.860: D/dalvikvm(24890): GC_FOR_ALLOC freed 34K, 1% free 35857K/36167K, paused 26ms
12-05 16:15:04.860: V/AppResult(24890): getIcon()
12-05 16:15:04.910: V/AppResult(24890): getIcon()
12-05 16:15:04.910: V/AppResult(24890): getIcon()
12-05 16:15:04.910: V/AppResult(24890): iconRecycled
12-05 16:15:04.910: V/AppResult(24890): iconRecycled
12-05 16:15:04.950: V/AppResult(24890): getIcon()
12-05 16:15:04.950: V/AppResult(24890): getIcon()
12-05 16:15:04.950: V/AppResult(24890): getIcon()
12-05 16:15:13.260: V/AppResult(24890): getIcon()
12-05 16:15:13.430: V/AppResult(24890): getIcon()
12-05 16:15:13.590: V/AppResult(24890): getIcon()
12-05 16:15:14.300: V/AppResult(24890): getIcon()
12-05 16:15:14.370: V/AppResult(24890): getIcon()
12-05 16:15:14.440: V/AppResult(24890): getIcon()

这是我的实施中的错误吗?看起来合并适配器以某种方式不再释放不再可见的视图。这个对吗?

编辑

我通过 MAT 运行它,结果如下:

java.util.ArrayList[32] @ 0x413beb88  144 19.833.288 
  \mScrapViews android.widget.AbsListView$RecycleBin @ 0x4129bd9040 19.833.496 
    .\mRecycler android.widget.ListView @ 0x412c5db8  896 23.635.384 
      ..+mFocusedView, mRealFocusedView android.view.ViewRootImpl @ 0x4133fae8 440 1.776 
        ..|+this$0 android.view.ViewRootImpl$2 @ 0x4136f540 Native Stack 16 16 
        ..|+[1] android.view.ViewRootImpl[2] @ 0x41340930 » 24 24 
        ..|+this$0 android.view.ViewRootImpl$AccessibilityInteractionConnectionManager @ 0x413157e8 » 16 16 
        ..|\Total: 3 entries       
      ..+mServedView, mNextServedView android.view.inputmethod.InputMethodManager @ 0x413511f8 » 104 368 
      ..+listview com.denper.addonsdetector.ui.InstallDateLister @ 0x412d8bd8 »
4

1 回答 1

0

看起来合并适配器以某种方式不再释放不再可见的视图。这个对吗?

如果“视图”是指“交替的标题文本视图”,那么当然MergeAdapter“不会释放不再显示的视图” - 如果MergeAdapter释放它们,则MergeAdapter当用户向后滚动时无法显示它们,因为它一旦发布,就没有办法让那些Views再次回来。

如果您所说的“视图”是指“像之前使用的那样的基本适配器”的内容,那么从一开始就MergeAdapter永远不会持有这些Views,因此不能持有它们。但是,增加类似方法的值可能getCount()会导致ListView.

于 2012-12-05T15:56:59.163 回答