码迷,mamicode.com
首页 > 其他好文 > 详细

Bitmap——基础

时间:2020-04-21 15:30:19      阅读:78      评论:0      收藏:0      [点我收藏+]

标签:roc   sam   两种方式有什么区别   程序包   ons   情况下   还需要   版本   自己的   

  在Android应用里,最耗费内存的就是图片资源。而且在Android系统中,读取位图Bitmap时,分给虚拟机中的图片的堆栈大小只有8M,如果超出了,就会出现OutOfMemory异常。所以,对于图片的内存优化,是Android应用开发中比较重要的内容。

  Bitmap13个的用法:

    Drawable 的用法

    BitmapDrawable的用法Bitmap

    Bitmap –>BitmapFactory.decodeResource

    Bitmap –>BitmapFactory.decodeStream

    Drawable → Bitmap

    从资源中获取Bitmap

    Bitmap → byte[]

    byte[] → Bitmap

    保存bitmap

    将图片按自己的要求缩放

    File图片转Bitmap

    图片转Bitmap

    bitmap的用法小结

及时回收Bitmap的内存
  Bitmap类有一个方法recycle(),从方法名可以看出意思是回收。这里就有疑问了,Android系统有自己的垃圾回收机制,可以不定期的回收掉不使用的内存空间,当然也包括Bitmap的空间。那为什么还需要这个方法呢?

  Bitmap类的构造方法都是私有的,所以开发者不能直接new出一个Bitmap对象,只能通过BitmapFactory类的各种静态方法来实例化一个Bitmap。

  仔细查看BitmapFactory的源代码可以看到,生成Bitmap对象最终都是通过JNI调用方式实现的。所以,加载 Bitmap到内存里以后,是包含两部分内存区域的。简单的说,一部分是Java部分的,一部分是C部分的。这个Bitmap对象是由Java部分分配的,不用的时候系统就会自动回收了,但是那个对应的C可用的内存区域,虚拟机是不能直接回收的,这个只能调用底层的功能释放。所以需要调用 recycle()方法来释放C部分的内存。从Bitmap类的源代码也可以看到,recycle()方法里也的确是调用了JNI方法了的。

  那如果不调用recycle(),是否就一定存在内存泄露呢?

  也不是的。Android的每个应用都运行在独立的进程里,有着独立的内存,如果整个进程被应用本身或者系统杀死了,内存也就都被释放掉了,当然也包括C部分的内存。

  Android对于进程的管理是非常复杂的。简单的说,Android系统的进程分为几个级别,系统会在内存不足的情况下杀死一些低优先级的进程,以提供给其它进程充足的内存空间。在实际项目开发过程中,有的开发者会在退出程序的时候使用 Process.killProcess(Process.myPid())的方式将自己的进程杀死,但是有的应用仅仅会使用调用 Activity.finish()方法的方式关闭掉所有的Activity。

经验分享:
  Android手机的用户,根据习惯不同,可能会有两种方式退出整个应用程序:

    一种是按Home键直接退到桌面;

    另一种是从应用程序的退出按钮或者按 Back键退出程序。

  那么从系统的角度来说,这两种方式有什么区别呢?

按Home键,应用程序并没有被关闭,而是成为了后台应用程序。

按Back键,一般来说,应用程序关闭了,但是进程并没有被杀死,而是成为了空进程(程序本身对退出做了特殊处理的不考虑在内)。

Android系统已经做了大量进程管理的工作,这些已经可以满足用户的需求。个人建议,应用程序在退出应用的时候不需要手动杀死自己所在的进程。对于应用程序本身的进程管理,交给Android系统来处理就可以了。应用程序需要做的,是尽量做好程序本身的内存管理工作。

  一般来说,如果能够获得Bitmap对象的引用,就需要及时的调用Bitmap的recycle()方法来释放Bitmap占用的内存空间,而不要等Android系统来进行释放。

缓存通用的Bitmap对象
  有时候,可能需要在一个Activity里多次用到同一张图片。比如一个Activity会展示一些用户的头像列表,而如果用户没有设置头像的话,则会显示一个默认头像,而这个头像是位于应用程序本身的资源文件中的。

  如果有类似上面的场景,就可以对同一Bitmap进行缓存。如果不进行缓存,尽管看到的是同一张图片文件,但是使用BitmapFactory类的方法来实例化出来的Bitmap,是不同的Bitmap对象。缓存可以避免新建多个Bitmap对象,避免内存的浪费。

经验分享:
  Web开发者对于缓存技术是很熟悉的。其实在Android应用开发过程中,也会经常使用缓存的技术。这里所说的缓存有两个级别,一个是硬盘缓存,一个是内存缓存。比如说,在开发网络应用过程中,可以将一些从网络上获取的数据保存到SD卡中,下次直接从SD卡读取,而不从网络中读取,从而节省网络流量。这种方式就是硬盘缓存。再比如,应用程序经常会使用同一对象,也可以放到内存中缓存起来,需要的时候直接从内存中读取。这种方式就是内存缓存。

压缩图片

  这里我们来算一下,在Android中,如果采用Config.ARGB_8888的参数去创建一个Bitmap,这是Google推荐的配置色彩参数,也是Android4.4及以上版本默认创建Bitmap的Config参数(Bitmap.Config.inPreferredConfig的默认值)。

  那么每一个像素将会占用4byte,如果一张手机照片的尺寸为1280×720。

    那么我们可以很容易的计算出这张图片占用的内存大小为 1280x720x4 = 3686400(byte) = 3.5M,一张未经处理的照片就已经3.5M了!

    显而易见,在开发当中,这是我们最需要关注的问题,否则分分钟OOM!
  那么,我们一般是如何处理Size这个重要的因素的呢?

  当然是调整Bitmap的大小到适合的程度啦!

  辛亏在BitmapFactory中,我们可以很方便的通过BitmapFactory.Options中的options.inSampleSize去设置Bitmap的压缩比

经验分享:
  如果程序的图片的来源都是程序包中的资源,或者是自己服务器上的图片,图片的大小是开发者可以调整的,那么一般来说,就只需要注意使用的图片不要过大,并且注意代码的质量,及时回收Bitmap对象,就能避免OutOfMemory异常的发生。
  如果程序的图片来自外界,这个时候就特别需要注意OutOfMemory的发生。一个是如果载入的图片比较大,就需要先缩小;另一个是一定要捕获异常,避免程序Crash。

Bitmap——基础

标签:roc   sam   两种方式有什么区别   程序包   ons   情况下   还需要   版本   自己的   

原文地址:https://www.cnblogs.com/hugeba/p/12730985.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!