2013-03-10 15 views
1

我正在打开图像,使用它并保存的项目中工作。图像可以是一个非常庞大的图像,就像一个摄像头PIC,所以我做的几件事情,以确保没有得到OutOfMemory异常(基本上是出现在这里http://developer.android.com/training/displaying-bitmaps/load-bitmap.html):在单独的线程中使用位图

  • 执行的宽度和高度的所有测量图像而无需实际打开它,使用:
BitmapFactory.Options options = new BitmapFactory.Options(); 
options.inJustDecodeBounds = true; 
BitmapFactory.decodeFile(image_path, options); 
  • 打开图像已经调整(inSampleSize)和全光照除Bitmap.Config.ARGB_8888(每像素4B)外,还包括每像素2B(每像素2B)。

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

  • 每回收其位图使用

  • 后,当显示在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(); 

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

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

非常感谢。

回答

2

有很多,当涉及到Android设备上的内存管理的疑难杂症的 - 尤其是当你在不同的设备进入混合抛出。去年,我在使用不同的Android应用程序玩内存管理方面浪费了一些时间,直到我发现Android-BitmapCache project,我取得了一些重大进展。

我建议大家对Android内存管理感兴趣的人到download and inspect Android-BitmapCache project,因为它包含了一些很棒的代码 - 所以做为第一步。

我建议你的第二步大多是看Google I/O: Memory Management for Android Apps,这样你就可以开始测试你的应用程序正在使用什么内存,并跟踪在哪里开始增加内存使用量。说到这一点 - 我不明白你为什么认为你会“用新线程完全释放内存空间” - 你从Android应用中产生的所有线程都将处于相同的进程中,因此无论哪个确切线程在内存使用方面正在运行一些任务。

最后,您可以通过使用android:largeHeap="true"来解决临时问题,但我认为您绝对应该瞄准更强大的解决方案。请记住,在某些设备上,您的应用可能无法正常工作(24MB堆,而您想要加载3000x3000的图片),但应用您可以在project I've linked中找到的所有最佳做法,我相信你会更好关闭。

+1

谢谢你的解释!我会检查这个项目和那个谈话......我对处理这些内存问题感兴趣。关于_largeHeap_,我已放置它,但没有看到任何区别。关于“完全无记忆”的事情是关于我身边的误解:我认为我可以打开另一个线程,而不是继承当前的流程消耗...但是因为它是一个孩子... – Xavi 2013-03-10 12:35:27

+0

@Xavi很高兴我能帮助,并随时提出更多问题 - 只要答案帮助你标记它。至于largeHeap - 这个属性是在Android 3.0中引入的,因此如果你的设备较旧 - 对于他们你需要[使用VMRuntime](http://stackoverflow.com/a/15010854/237858)。 – kape123 2013-03-12 03:54:21