我正在使用的Android应用程序上出现位图问题。可能发生的情况是,该应用程序从网站下载图像,将其保存到设备,将它们作为位图加载到内存中,并显示在阵列列表中,并显示给用户。首次启动该应用程序时,所有这些都可以正常工作。但是,我为删除图像的用户添加了一个刷新选项,上面概述的过程从头开始。

我的问题:通过使用refresh选项,旧图像仍在内存中,因此我很快就会收到OutOfMemoryErrors。因此,如果要刷新图像,则可以让它遍历arraylist并回收旧图像。但是,当应用程序将新图像加载到arraylist时,它崩溃并显示“尝试使用回收的位图”错误。

据我了解,回收位图会破坏位图并释放其内存供其他对象使用。如果要再次使用位图,则必须重新初始化。我相信当新文件加载到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();
    }
};

}

最佳答案

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

我可能会假设某些ImageView显示了您的位图,并且它们保留了对该位图的引用。旧的位图仍然显示时,您将无法删除它们。因此,可能的解决方案是也清除ImageVIews。之后,您可以清除阵列并用新图像填充它。

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

所有这些只是一个假设,因为我看不到您的完整代码。

关于android - Android “Trying to use recycled bitmap”错误?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3032497/

10-12 00:12
查看更多