java - Android ListActivity 与位图和垃圾收集问题

标签 java android garbage-collection listactivity

我有一个 ListActivity,在其中我使用扩展 SimpleCursorAdapter 的类设置列表项。我正在重写 bindView 来设置我的 Views。我有一些 TextViewsImageViews。这是我在光标适配器中设置列表项的方法:

String variableName = "drawable/q" + num + "_200px";
int imageResource = context.getResources().getIdentifier(variableName, "drawable", context.getPackageName());
if (imageResource != 0 ) {
    // The drawable exists
    Bitmap b = BitmapFactory.decodeResource(context.getResources(), imageResource);
    width = b.getWidth();
    height = b.getHeight();
    imageView.getLayoutParams().width = (int) (width);
    imageView.getLayoutParams().height = (int) (height);
    imageView.setImageResource(imageResource);
} else {
    imageView.setImageResource(R.drawable.25trans_200px);
}

我遇到的问题是每当我使用 setListAdapter 更新列表时,我都会收到大量垃圾收集:

D/dalvikvm(18637): GC_EXTERNAL_ALLOC freed 125K, 51% free 2710K/5447K, external 2022K/2137K, paused 75ms
D/dalvikvm(18637): GC_EXTERNAL_ALLOC freed 30K, 51% free 2701K/5447K, external 2669K/2972K, paused 64ms
D/dalvikvm(18637): GC_EXTERNAL_ALLOC freed 23K, 51% free 2713K/5447K, external 3479K/3579K, paused 53ms
D/dalvikvm(18637): GC_EXTERNAL_ALLOC freed 22K, 51% free 2706K/5447K, external 3303K/3352K, paused 64ms
D/dalvikvm(18637): GC_EXTERNAL_ALLOC freed 21K, 51% free 2722K/5447K, external 3569K/3685K, paused 102ms
D/dalvikvm(18637): GC_EXTERNAL_ALLOC freed 23K, 50% free 2755K/5447K, external 3499K/3605K, paused 65ms
D/dalvikvm(18637): GC_EXTERNAL_ALLOC freed 23K, 50% free 2771K/5447K, external 4213K/4488K, paused 53ms
D/dalvikvm(18637): GC_EXTERNAL_ALLOC freed 18K, 49% free 2796K/5447K, external 5057K/5343K, paused 75ms
D/dalvikvm(18637): GC_EXTERNAL_ALLOC freed 28K, 49% free 2803K/5447K, external 5944K/5976K, paused 53ms
D/dalvikvm(  435): GC_EXPLICIT freed 6K, 54% free 2544K/5511K, external 1625K/2137K, paused 50ms
D/dalvikvm(  165): GC_EXPLICIT freed 85K, 52% free 2946K/6087K, external 4838K/5980K, paused 111ms
D/dalvikvm(  448): GC_EXPLICIT freed 1K, 54% free 2540K/5511K, external 1625K/2137K, paused 50ms
D/dalvikvm(  294): GC_EXPLICIT freed 8K, 55% free 2598K/5703K, external 1625K/2137K, paused 64ms

我可以做什么来避免这种情况?这导致我的用户界面变得迟缓,当我滚动时也是如此。

最佳答案

  1. 您不需要加载位图只是为了获取长度和宽度。您可能想看看 ImageView 的 scaleType属性(property)。这将根据加载的图像调整 ImageView 的边界。
  2. 您的代码意味着您有基于数字的多个图像状态。您可能想查看LevelListDrawable XML为了那个原因。基本上,您可以设置可绘制的列表,这些可绘制的列表是根据您传递给它们的数字来选择的。如果您分配 LevelListDrawable XML 或代码中的 ImageView。您可能需要做的就是调用 imageView.setImageLevel(num) .

bindView 是动画列表时的一个关键方法。当 ListView 滚动并且新项目由于出现而加载时,它会被调用。 BindView 在 UI 线程上被调用,这意味着动画在完成之前无法继续。通常这不是问题,因为您只是分配变量。在此代码中,您调用 Bitmap b = BitmapFactory.decodeResource(context.getResources(), imageResource);必须使用昂贵的 NAND 闪存。您可以使用StrictMode顺便检测一下这类问题。

位图在不再使用时确实会从内存中卸载,但这不是立即的,必须调用 GC。 Android 提供了一种方法来删除位图携带的大字节数组数据 Bitmap.recycle()方法。这有望解决 OutOfMemoryError's .

如果上述方法由于某种原因不起作用,那么您将不得不处理涉及线程和回调的更复杂的解决方案。

如果您需要帮助,请告诉我。如果可以请说明为什么需要图像的宽度和高度?

关于java - Android ListActivity 与位图和垃圾收集问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9960588/

相关文章:

java - 如何使 ArrayList 在 java 中用作二维数组?

android - 你能给我一个简短的 Android 代码来创建这个吗?

java - 简单的project/lib和project/web/WEB-INF/lib有什么区别?

java - JButton 操作不在 JTable 内部执行

Android - 操作栏选项卡 + 对话框

android - 还需要BaseGameUtils吗? (实现Android排行榜)

php - 在 PHP 中强制释放内存

java - JVM 堆转储未引用的对象

java - Spring单例导致内存泄漏

java - 告诉 jaxb 不要删除下划线