Android“尝试使用回收位图”错误?

发布于 2024-09-05 06:57:25 字数 1609 浏览 3 评论 0原文

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

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

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

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();
    }
};

}

I am running into a problem with bitmaps on an Android application I am working on. What is suppose to happen is that the application downloads images from a website, saves them to the device, loads them into memory as bitmaps into an arraylist, and displays them to the user. This all works fine when the application is first started. However, I have added a refresh option for the user where the images are deleted, and the process outlined above starts all over.

My problem: By using the refresh option the old images were still in memory and I would quickly get OutOfMemoryErrors. Thus, if the images are being refreshed, I had it run through the arraylist and recycle the old images. However, when the application goes to load the new images into the arraylist, it crashes with a "Trying to use recycled bitmap" error.

As far as I understand it, recycling a bitmap destroys the bitmap and frees up its memory for other objects. If I want to use the bitmap again, it has to be reinitialized. I believe that I am doing this when the new files are loaded into the arraylist, but something is still wrong. Any help is greatly appreciated as this is very frustrating. The problem code is below. Thank you!

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();
    }
};

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

混吃等死 2024-09-12 06:57:25

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

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

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

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

You don't actually need to call recycle method here. Refresh button should just clear the array, garbage collector will free the memory later. If you get OutOfMemory it means some other objects are still referencing your old images and Garbage Collector can't remove them.

I may asume that some ImageViews display your bitmaps and they keep references to that bitmaps. You can't remove old bitmaps while they're still displayed. So a possible solution is to clear ImageVIews too. After that you can clear the array and fill it with new images.

Recycle frees the memory but some ImageView is still displaying the bitmap and it can't do that after recycle, that's why you get "Trying to use recycled bitmap".

These all are just an assumptions because I can't see your complete code.

猛虎独行 2024-09-12 06:57:25

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

If the memory is very large, you'd better recycle the bitmap yourself.
GC can't be controled.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文