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


         忽略掉遥远的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中生成的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值