您的位置:首页 > 移动开发 > Android开发

Android开发Bitmap在Native层与Java层内存的两种生成方式

2014-08-26 14:24 369 查看
         忽略掉遥远的Android2.2及之前版本,本文讨论基于Android4.4,也适用于4.x版本。

         项目开发中遇到一个内存溢出问题,抓内存数据分析,发现有的bitmap在java层生成,占用的Dalvik虚拟机堆栈,这也符合我当前粗略的认知,恕本人知识浅陋。原来研究内存,一直认为Android2.2之后的各个版本Android中bitmap都是通过JNI回调到Java层,最后是在Java层真正new出来的bitmap(这个在本文最后取源码做了说明)。可是抓到的信息发现了一个Native stack上的Bitmap,如下图所示。



         然后查看资料和源码发现,的确这个是在Native Stack上创建的,因为它是调用BitmapFactory.decodeStream方法,创建出一个bitmap,decodeStream直接调用 JNI 的 nativeDecodeAsset() 来完成decode,这点不同于使用java层的createBitmap。所以这个是在Native层占用的内存。

private static Bitmap readBitMap(Context context, int resId) {
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inPreferredConfig = Bitmap.Config.RGB_565;
opt.inPurgeable = true;
opt.inInputShareable = true;
// 获取资源图片
InputStream is = context.getResources().openRawResource(resId);
return BitmapFactory.decodeStream(is, null, opt);
}
这里代码搬一下别人的代码来说明,如何做就在Native层生成Bitmap了,如上代码,Options需要设置两个参数, inPurgeable 、inInputShareable为true。其实看源码分析,如果调用decodeStream方法,其实只要 inPurgeable
为true就够了,inInputShareable是默认为true的,不过别的方法就需要双双为ture,稍后源码分析详述此处。大家只要如上调用就可以让bitmap在Native上了。具体性能会不会有影响,稍后我会写几个demo验证一下。

         如图就是源码中的调用,图为BitmapFactory这个源码中decodeStream方法的具体实现,我们可以看到是调用的Native方法,可能有人会问了如果走了else呢,其实else里面的方法跟进去就会发现,也是做了一些处理后,调用nativeDecodeAsset来生成的bitmap。



说到这里我们必须说一个重要的事情,大家千万别以为去调用Native方法就一定是在Native层占用的内存,例如Bitmap.java中的createBitmap也是调用的JNI方法,但其实又反过来回调的Java中的New来做的生成操作。具体的这个地方,我会专门写一篇文章来讲Bitmap和BitmapFactory的源码,从源码中彻底分析一下为什么就是在Native中生成的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐