这与this类似,但解决方案不起作用。
问题是ListView
的滚动非常缓慢,这是因为有很多很多的GC。我使用holder pattern(视图缓存),如下面的代码所示:
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.eventrow, parent, false);
holder = new ViewHolder();
holder.title = (TextView) convertView.findViewById(R.id.eventTitle);
holder.place = (TextView) convertView.findViewById(R.id.eventPlace);
convertView.setTag(holder);
} else {
// Get the ViewHolder back to get fast access to the TextView
// and the ImageView.
holder = (ViewHolder) convertView.getTag();
}
// Bind the data efficiently with the holder.
holder.title.setText(((EventItem) getItem(position)).getTitle());
holder.place.setText(((EventItem) getItem(position)).getPlace_name());
return convertView;
}
我从列表视图和行中删除了cacheColorHint
和自定义选择器:
<ListView
android:id="@+id/android:list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
这就是日志的样子:
08-20 19:36:24.286: D/dalvikvm(12036): GC_EXTERNAL_ALLOC freed 364K, 46% free 3944K/7239K, external 1196K/1445K, paused 54ms
08-20 19:36:24.356: D/dalvikvm(12036): GC_EXTERNAL_ALLOC freed 228K, 49% free 3716K/7239K, external 1721K/1970K, paused 52ms
08-20 19:36:24.456: D/dalvikvm(12036): GC_EXTERNAL_ALLOC freed 5K, 49% free 3726K/7239K, external 2214K/2463K, paused 50ms
08-20 19:36:24.546: D/dalvikvm(12036): GC_EXTERNAL_ALLOC freed 2K, 49% free 3726K/7239K, external 2214K/2463K, paused 43ms
08-20 19:36:24.636: D/dalvikvm(12036): GC_EXTERNAL_ALLOC freed 2K, 49% free 3726K/7239K, external 2214K/2463K, paused 44ms
08-20 19:36:24.696: D/dalvikvm(12036): GC_EXTERNAL_ALLOC freed <1K, 49% free 3726K/7239K, external 2214K/2463K, paused 50ms
08-20 19:36:24.766: D/dalvikvm(12036): GC_EXTERNAL_ALLOC freed <1K, 49% free 3726K/7239K, external 2214K/2463K, paused 46ms
08-20 19:36:24.846: D/dalvikvm(12036): GC_EXTERNAL_ALLOC freed <1K, 49% free 3726K/7239K, external 2214K/2463K, paused 46ms
08-20 19:36:24.906: D/dalvikvm(12036): GC_EXTERNAL_ALLOC freed <1K, 49% free 3726K/7239K, external 2214K/2463K, paused 46ms
08-20 19:36:24.986: D/dalvikvm(12036): GC_EXTERNAL_ALLOC freed <1K, 49% free 3726K/7239K, external 2214K/2463K, paused 46ms
08-20 19:36:25.056: D/dalvikvm(12036): GC_EXTERNAL_ALLOC freed <1K, 49% free 3726K/7239K, external 2214K/2463K, paused 47ms
08-20 19:36:25.136: D/dalvikvm(12036): GC_EXTERNAL_ALLOC freed <1K, 49% free 3726K/7239K, external 2214K/2463K, paused 46ms
08-20 19:36:25.196: D/dalvikvm(12036): GC_EXTERNAL_ALLOC freed <1K, 49% free 3726K/7239K, external 2214K/2463K, paused 46ms
08-20 19:36:25.296: D/dalvikvm(12036): GC_EXTERNAL_ALLOC freed <1K, 49% free 3726K/7239K, external 2214K/2463K, paused 48ms
08-20 19:36:25.356: D/dalvikvm(12036): GC_EXTERNAL_ALLOC freed <1K, 49% free 3726K/7239K, external 2214K/2463K, paused 43ms
08-20 19:36:34.596: D/dalvikvm(12036): GC_EXTERNAL_ALLOC freed 7K, 49% free 3740K/7239K, external 2214K/2463K, paused 51ms
08-20 19:36:34.656: D/dalvikvm(12036): GC_EXTERNAL_ALLOC freed 1K, 49% free 3739K/7239K, external 2214K/2463K, paused 50ms
08-20 19:36:34.746: D/dalvikvm(12036): GC_EXTERNAL_ALLOC freed <1K, 49% free 3739K/7239K, external 2214K/2463K, paused 50ms
修改
似乎(几乎)仅在ListFragment
首次膨胀时出现问题。首先向下滚动,然后向上滚动。之后,GC并不常见。但有时每次滚动时都会出现GC。我在这里看不到规律性。
PLUS 我可以在HTC Desire(2.3.7 MIUI)上看到问题,但不能在Sasmung Galaxy ACE(2.1)上看到问题。它只会让人感到困惑......
不太令人满意的解决方案: 当我使用
android:scrollingCache="false"
android:animationCache="false"
在我的listview中似乎没问题。但是文档说如果我理解得那应该是完全不同的,所以我有点困惑。
我哪里弄错了?怎样做才能拥有流畅的滚动列表视图?或者禁用scrollingCache
会产生一些我现在看不到的负面影响吗?
答案 0 :(得分:3)
android:scrollingCache="false"
是解决方案。
文档说:
设置为true时,列表在滚动期间使用绘图缓存。这个 使渲染更快但使用更多内存。
现在这并没有给我们任何关于实现细节的提示。我有一个想法,没有投入数小时的代码分析。 出于缓存目的,Google会在自己的文档中推荐使用WeakReferences或WeakHashMaps。但看起来Dalvik VM有点过于急于杀掉这些引用并导致它们每次都重建。这解释了巨大的GC活动和缓慢的用户体验。
链接: 关于因bug而导致的无用WeakReferences的博客:http://chriswstewart.com/post/14199645893/improving-the-android-listview Dalvik VM错误讨论:https://groups.google.com/forum/#!topic/android-developers/66uw2t84rME
答案 1 :(得分:1)
确保你有ListView后面的背景和/或windowBackground,我之前已经看到过这样的问题。
答案 2 :(得分:-1)
试
listView.setCacheColorHint(0);
&
protected void onDestroy() {
System.gc();
super.onDestroy();
}