1

我正在一个项目中工作,该项目可以打开图像,使用它并保存。该图像可以是一个非常大的图像,例如相机图片,因此我正在做几件事以确保不会出现 OutOfMemory 异常(基本上出现在这里http://developer.android.com/training/displaying-bitmaps/load-位图.html):

  • 在不实际打开图像的情况下执行图像的所有宽度和高度测量,使用:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(image_path, options);
  • 打开的图像已经调整大小(inSampleSize)并使用Bitmap.Config.RGB_565(每像素 2B)除了Bitmap.Config.ARGB_8888(每像素 4B)。

  • 使用临时文件在内存中没有很多位图(实际上我只有一个大多数情况,应用掩码时最多 2 个)。

  • 使用后回收每个位图

  • 当在 a 中显示结果时ImageView,打开它已经缩放到屏幕尺寸。

但是,在某些情况下,当一次只加载一个位图来完成某项工作(旋转图像、微调调整大小、应用蒙版等)是不可能的,并且主要是在中等范围或旧设备中,我获得OutOfMemory 异常

我已经开始添加所有在后台作业中工作的图像,如下所示(好的,我是新手):

ProgressDialog dialog = ProgressDialog.show(this, null, "Please wait", true, false);
new Thread(new BackgroundJob(this, new Runnable() {
    public void run() {
        ImageHelper.ImageManipulation(image_path); 
    }
}, dialog, new Handler())).start();

我希望通过这个新线程获得一个完全可用的内存空间来执行图像处理任务,但我发现应用程序出于相同的原因在相同的点崩溃。线程被创建为子进程(好的),但共享最大堆和当前使用的内存......

有没有办法打开一个线程来执行具有更多内存的图像操作(例如,释放活动本身使用的内存,因为它是另一个线程)?

非常感谢你。

4

2 回答 2

3

在 Android 设备上的内存管理方面存在很多问题——尤其是当您将不同的设备混入其中时。去年我在我制作的不同 Android 应用程序中浪费了内存管理,直到我找到了Android-BitmapCache 项目,我才取得了一些重大进展。

我建议所有对 Android 内存管理感兴趣的人下载并检查 Android-BitmapCache 项目,因为它包含一些很棒的代码——所以第一步就是这样做。

我建议您的第二步是观看Google I/O:Android 应用程序的内存管理,这样您就可以开始准确地测试您的应用程序使用了多少内存,并跟踪确切的内存使用量开始增加的位置。说到这一点 - 我不明白你为什么认为你会得到“新线程的完全可用内存空间” - 你从你的 Android 应用程序产生的所有线程都将在同一个进程下,所以哪个确切并不重要当涉及内存使用时,线程正在运行一些任务。

And finally, you can fix problem temporary by using android:largeHeap="true", but I think you should definitely aim toward more robust solution. Keep in mind that it's possible that on some devices you app will simply not work (24MB heap and you want to load image that's 3000x3000), but with applying all best practices you can find in project I've linked I'm sure you'll be much better off.

于 2013-03-10T10:44:32.073 回答
1

您可以使用池线程来执行多个线程,与为每个线程创建新的 Thread 对象相比,它的“昂贵”方式更少。

本指南可能会有所帮助:http: //developer.android.com/training/multiple-threads/create-threadpool.html

或者这个 http://android-developers.blogspot.com/2009/05/painless-threading.html

于 2013-03-10T10:44:00.680 回答