android - ListView 中的大量垃圾收集

标签 android listview garbage-collection

我有一个使用自定义适配器的 ListView。自定义适配器的 getView 使用所有推荐的做法:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    SuscriptionsViewsHolder holder;
    ItemInRootList item = mItemsInList.get(position);

    if (convertView == null) {
         convertView = mInflater.inflate(R.layout.label, null);

         holder = new SuscriptionsViewsHolder();
         holder.label = (TextView) convertView.findViewById(R.id.label_label);
         holder.icon = (ImageView) convertView.findViewById(R.id.label_icon);

        convertView.setTag(holder);
    } else {
        holder = (SuscriptionsViewsHolder) convertView.getTag();
    }

    String text = String.format("%1$s (%2$s)", item.title, item.unreadCount);
    holder.label.setText(text);
    holder.icon.setImageResource(item.isLabel ? R.drawable.folder : R.drawable.file );

    return convertView;
}

但是当我滚动时,由于垃圾收集繁重,它很慢:

GC_EXTERNAL_ALLOC freed 87K, 48% free 2873K/5447K, external 516K/519K, paused 30ms
GC_EXTERNAL_ALLOC freed 7K, 48% free 2866K/5447K, external 1056K/1208K, paused 29ms
GC_EXTERNAL_ALLOC freed <1K, 48% free 2866K/5447K, external 1416K/1568K, paused 28ms
GC_EXTERNAL_ALLOC freed 5K, 48% free 2865K/5447K, external 1600K/1748K, paused 27ms
GC_EXTERNAL_ALLOC freed <1K, 48% free 2865K/5447K, external 1780K/1932K, paused 30ms
GC_EXTERNAL_ALLOC freed 2K, 48% free 2870K/5447K, external 1780K/1932K, paused 26ms
GC_EXTERNAL_ALLOC freed 2K, 48% free 2870K/5447K, external 1780K/1932K, paused 25ms
GC_EXTERNAL_ALLOC freed <1K, 48% free 2870K/5447K, external 1780K/1932K, paused 26ms
GC_EXTERNAL_ALLOC freed 3K, 48% free 2870K/5447K, external 1780K/1932K, paused 25ms
GC_EXTERNAL_ALLOC freed <1K, 48% free 2870K/5447K, external 1780K/1932K, paused 29ms
GC_EXTERNAL_ALLOC freed <1K, 48% free 2870K/5447K, external 1780K/1932K, paused 29ms
GC_EXTERNAL_ALLOC freed <1K, 48% free 2871K/5447K, external 1780K/1932K, paused 28ms
GC_EXTERNAL_ALLOC freed <1K, 48% free 2871K/5447K, external 1780K/1932K, paused 26ms
GC_EXTERNAL_ALLOC freed <1K, 48% free 2870K/5447K, external 1780K/1932K, paused 27ms
GC_EXTERNAL_ALLOC freed <1K, 48% free 2870K/5447K, external 1780K/1932K, paused 29ms
GC_EXTERNAL_ALLOC freed <1K, 48% free 2870K/5447K, external 1780K/1932K, paused 26ms
GC_EXTERNAL_ALLOC freed <1K, 48% free 2870K/5447K, external 1780K/1932K, paused 34ms

似乎出了什么问题?

编辑@12:47 GMT:

事实上,它比这稍微复杂一些。我的应用程序 UI 基于 2 个部分。一个是屏幕的大脑,创建 View 、处理用户输入等。另一个是 Fragment如果设备有 android 3.0,否则它是 Activity .

GC 发生在我的 Nexus One 2.3.3 设备上,因此使用 Activity .我没有带我的 Xoom 来测试 Fragment 的行为.

如果需要,我可以发布源代码,但让我尝试解释一下:

  • RootList是 UI 的大脑。它包含 :
    • 一个 List<>将放置在 ListView 中的项目数.
    • 从 SQLite db 构建此列表的方法
    • 一个自定义的 BaseAdapter,基本上只包含上面粘贴的 getView 方法
  • RootListActivityListActivity , 哪个:
    • 使用 XML 布局
    • 布局当然有一个 ID 为 android.id.list 的 ListView 。
    • Activity回调被转发到 RootList使用创建 Activity 时创建的 RootList 实例的类(构造函数,而不是 onCreate)
    • onCreate , 我调用 RootList的方法将创建项目列表,并将列表数据设置为从 BaseAdapter 派生的自定义类的新实例

格林威治标准时间 5 月 17 日晚上 9:36 编辑:

这是 Activity 的代码和执行这些操作的类。 http://pastebin.com/EgHKRr4r

最佳答案

我发现了问题。我的 Activity XML 布局是:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <include android:id="@+id/rootlist_header" layout="@layout/pre_honeycomb_action_bar" />

    <ListView android:id="@android:id/list"
        android:layout_below="@id/rootlist_header"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        android:textColor="#444444"
        android:divider="@drawable/list_divider"
        android:dividerHeight="1px"
        android:cacheColorHint="#00000000" />

</RelativeLayout>

如果我删除 android:cacheColorHint="#00000000",重 GC 出来了,滚动是 smooth! :)

我真的不知道为什么要设置这个参数,因为我不需要它。也许我复制粘贴太多,而不是实际构建我的 XML 布局。

感谢您的支持,非常感谢您的帮助。

关于android - ListView 中的大量垃圾收集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5977718/

相关文章:

java - 如何管理内存中的视频帧

0 台设备支持 Android 应用

android - 如何获取扩展 ListView 项中复选框的 ID?

java - wicket 树对 "not direct" child 有用吗?

c# - winforms中ListView的子项不显示

java - 如何从 JVM 内存中清除明确的敏感数据?

java - JVM 的 GC 事件的编程通知

android - Kotlin float ,带 2 位小数到字符串,没有精度损失

javascript - 内存处理与性能

java - 使用 notifyDataSetChanged() 时,Android API ListView 不会更新;