Android平台在图片处理方面经常会出现OOM的问题,在去年开发的一个项目中,我也一直被这个问题所困扰,在这方面也搜集了许多的资料,今天仅仅针对Android平台的Bitmap说事儿,今后再对内存的问题做详细的探讨,android平台对图片解码这块确实设置的有内存上限,在解码Bitmap的时候android平台会对其需要占用的内存进行Check,一旦需要的内存超越上限,则直接报错,下面援引邓凡平老师的解释:
createBitmap好像有一个参数,可以绕过虚拟机的堆栈检查。内存报错其实是先检查是否超过限制,比如最大16M,你要分配32M,检查的时候超标,则会报错。除此之外,没有别的办法可以解决该问题。我们当时测试了30M的图片分配,如果不加该参数,则必然报错。加了就没事了。该参数是hidden的。你必须用源码编译才可以。而只有那个函数可以用。其余都用不了。该参数是BitmapFactory.options类的public boolean inNativeAlloc。不过4.0已经去掉该参数了。所以这个办法可能也不行。
你最好分析下你的图片尺寸大小,实在不行的话,把buffer传递给native层,然后在native层做修改。记住我刚才说的,内存检查是Bitmap自己去check的。native层其实malloc/new多大内存都无所谓,只要你不去check。
这个参数就是:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inNativeAlloc = true;
接下来我查证了SDK的文档,其中BitmapFactory.Options中并没有inNativeAlloc这个参数,为了查证这个参数,我继续查看了Android系统源代码的BitmapFactory部分,在其中找到了该参数,以下是对该参数的描述:
我在Android Developers 论坛上找到了一段话:
> On Wed, Jun 8, 2011 at 10:17 AM, Erik R wrote:
> > I'm working on a simple image manipulation app that requires opening
> > bitmaps at full resolution, which of course results in OutOfMemory
> > issues. I know that the short answer is to simply use less memory via
> > BitmapFactory's inSampleSize Option to downsample the bitmap, but for
> > this app I really would like to retain the full resolution for
> > editing. One solution I have been investigating is loading the bitmap
> > entirely on the native heap, after learning that the memory limitation
> > is only imposed within the Dalvik VM heap. A look into the Android
> > source code revealed that this is already the case... BitmapFactory
> > uses native methods to load a bitmap on the native heap, while
> > maintaining a reference to it on the VM heap. The issue then is that
> > it appears the native memory used by the bitmap is actually counted
> > against the available VM memory, when it really isn't there. A look
> > into the stock Camera and Gallery apps' source revealed that they get
> > around this by using an additional BitmapFactory Option,
> > inNativeAlloc. I was able to find this field in the Java code for
> > BitmapFactory:
但是这个参数是hidden的,在使用中需要带源码编译才可以。
总之,使用这个参数确实能避开内存检查,并且系统自带的图片浏览器中也使用了这个参数,但是注意,这个参数仅仅在4.0以下平台适用。