【问题标题】:Android "Trying to use recycled bitmap" error?Android“尝试使用回收的位图”错误?
【发布时间】:2011-03-03 05:29:03
【问题描述】:

我正在处理的 Android 应用程序上遇到位图问题。假设发生的是应用程序从网站下载图像,将它们保存到设备,将它们作为位图加载到内存中并放入数组列表中,然后将它们显示给用户。首次启动应用程序时,这一切正常。但是,我为删除图像的用户添加了一个刷新选项,并且上面概述的过程从头开始。

我的问题:通过使用刷新选项,旧图像仍在内存中,我很快就会得到 OutOfMemoryErrors。因此,如果正在刷新图像,我让它通过 arraylist 运行并回收旧图像。但是,当应用程序将新图像加载到数组列表中时,它会因“尝试使用回收的位图”错误而崩溃。

据我了解,回收位图会破坏位图并释放其内存以供其他对象使用。如果我想再次使用位图,它必须重新初始化。我相信当新文件加载到数组列表中时我正在这样做,但仍然有问题。非常感谢任何帮助,因为这非常令人沮丧。问题代码如下。谢谢!

public void fillUI(final int refresh) { 
// Recycle the images to avoid memory leaks
if(refresh==1) {
    for(int x=0; x<images.size(); x++)
        images.get(x).recycle();
    images.clear();
    selImage=-1; // Reset the selected image variable
}
final ProgressDialog progressDialog = ProgressDialog.show(this, null, this.getString(R.string.loadingImages));
// Create the array with the image bitmaps in it
new Thread(new Runnable() {
    public void run() {
        Looper.prepare();
        File[] fileList = new File("/data/data/[package name]/files/").listFiles();
        if(fileList!=null) {
            for(int x=0; x<fileList.length; x++) {
                try {
                    images.add(BitmapFactory.decodeFile("/data/data/[package name]/files/" + fileList[x].getName()));
                } catch (OutOfMemoryError ome) {
                    Log.i(LOG_FILE, "out of memory again :(");
                }
            }
            Collections.reverse(images);
        }
        fillUiHandler.sendEmptyMessage(0);
    }
}).start();

fillUiHandler = new Handler() {
    public void handleMessage(Message msg) {
        progressDialog.dismiss();
    }
};

}

【问题讨论】:

    标签: android bitmap


    【解决方案1】:

    您实际上不需要在这里调用回收方法。刷新按钮应该只是清除数组,垃圾收集器稍后会释放内存。如果您得到 OutOfMemory,则意味着其他一些对象仍在引用您的旧图像,而垃圾收集器无法删除它们。

    我可能假设某些 ImageView 会显示您的位图,并且它们会保留对该位图的引用。当它们仍然显示时,您不能删除旧位图。所以一个可能的解决方案是也清除 ImageVIews。之后,您可以清除数组并用新图像填充它。

    回收会释放内存,但某些 ImageView 仍在显示位图,并且在回收后无法执行此操作,这就是为什么您会收到“尝试使用回收的位图”。

    这些都只是假设,因为我看不到你的完整代码。

    【讨论】:

    • 注册。 “您实际上不需要在这里调用回收方法”。嗯,有趣。到目前为止,我在网上阅读的内容我也认为这是这样做的方法,应该被调用。我也一直这样称呼它。在使用大量位图时,我也遇到了内存问题。正如 Romain Guy 所建议的,减少内存问题的一个好方法是使用 SoftReference 缓存。例如,他在shelves.googlecode.com/svn/trunk/Shelves/src/org/… 关于SoftReferences:java.sun.com/j2se/1.5.0/docs/api/java/lang/ref/… 中使用它
    • 回收很好,但不是必需的。 GC 无论如何都会清理内存。回收只会更快地清洁它。我是这么理解的。
    • 谢谢费多尔!在清除和重新创建数组之前,我确保将所有使用位图的视图清空,这样就成功了。 :)
    【解决方案2】:

    如果内存很大,最好自己回收位图。 GC无法控制。

    【讨论】:

      猜你喜欢
      • 2011-12-20
      • 2017-10-01
      • 2013-07-12
      • 1970-01-01
      • 1970-01-01
      • 2012-12-17
      • 2014-04-03
      • 2015-07-18
      相关资源
      最近更新 更多