/**
 * 以最省内存的方式读取本地资源的图片
 * @param context
 *@param resId
 * @return
 */
 private 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);
 }




1.尽量不要使用setImageBitmap或setImageResource或BitmapFactory.decodeResource来设置一张大图,因为这些函数在完成decode后,最终都是通过Java层的createBitmap来完成的,需要消耗更多内存.

2.因此,改用先通过BitmapFactory.decodeStream方法,创建出一个bitmap,再将其设为ImageView的 source。decodeStream最大的秘密在于其直接调用 JNI >> nativeDecodeAsset()来完成decode,无需再使用java层的createBitmap,从而节省了java层的空间.

3.如果在读取时加上图片的Config参数,可以更有效减少加载的内存,从而有效阻止抛出out of Memory异常另外,decodeStream直接拿的图片来读取字节码了,不会根据机器的各种分辨率来自动适应,使用了decodeStream之后,需要在hdpi和mdpi,ldpi中配置相应的图片资源,否则在不同分辨率机器上都是同样大小(像素点数量),显示出来的大小就不对了.

4.BitmapFactory.Options.inPreferredConfig
1)ALPHA_8:数字为8,图形参数应该由一个字节来表示,应该是一种8位的位图
ARGB_4444:4+4+4+4=16,图形的参数应该由两个字节来表示,应该是一种16位的位图.
ARGB_8888:8+8+8+8=32,图形的参数应该由四个字节来表示,应该是一种32位的位图.
RGB_565:5+6+5=16,图形的参数应该由两个字节来表示,应该是一种16位的位图.

2)
ALPHA_8,ARGB_4444,ARGB_8888都是透明的位图,也就是所字母A代表透明.
ARGB_4444:意味着有四个参数,即A,R,G,B,每一个参数由4bit表示.
ARGB_8888:意味着有四个参数,即A,R,G,B,每一个参数由8bit来表示.
RGB_565:意味着有三个参数,R,G,B,三个参数分别占5bit,6bit,5bit.

 3)用ARBG_4444色彩模式加载图片:

Android中有四种,分别是:

ALPHA_8:每个像素占用1byte内存

ARGB_4444:每个像素占用2byte内存

ARGB_8888:每个像素占用4byte内存

RGB_565:每个像素占用2byte内存

Android默认的色彩模式为ARGB_8888,这个色彩模式色彩最细腻,显示质量最高。但同样的,占用的内存也最大。

 

5.BitmapFactory.Options.inPurgeable;
1)如果 inPurgeable 设为True的话表示使用BitmapFactory创建的Bitmap用于存储Pixel的内存空间在系统内存不足时可以被回收。

在应用需要再次访问Bitmap的Pixel时(如绘制Bitmap或是调用getPixel),系统会再次调用BitmapFactory decoder重新生成Bitmap的Pixel数组。

为了能够重新解码图像,bitmap要能够访问存储Bitmap的原始数据.

2)在inPurgeable为false时表示创建的Bitmap的Pixel内存空间不能被回收,这样BitmapFactory在不停decodeByteArray创建新的Bitmap对象。不同设备的内存不同,因此能够同时创建的Bitmap个数可能有所不同,200个bitmap足以使大部分的设备重新OutOfMemory错误.

3)当isPurgable设为true时,系统中内存不足时,可以回收部分Bitmap占据的内存空间,这时一般不会出现OutOfMemory 错误.