Android控件使用注意事项 ——> ImageView

来源:互联网 发布:openwrt 串口编程 编辑:程序博客网 时间:2024/04/28 05:24


一:BitmapFactory.decodeResource 与 decodeStream

android应用加载本地大图(res资源文件或者sdcard外部文件)时,经常容易出现内存溢出问题.

常见使用错误如,开发应用的滑动引导页面时,使用ViewPager加载了几张res资源中的大图,在部分低配置机型上会出现OOM错误.

错误如下图所示:

问题分析:

ImageView的setImageBitmap、setImageResource或者BitmapFactory.decodeResource,这些函数调用,完成decode之后,

最终都是通过Java层的createBitmap来完成的,需要消耗更多内存.

解决办法是,使用BitmapFactory.decodeStream(InputStream is, Rect outPadding, Options opts)方法,创建出一个Bitmap对象,

再使用setImageBitmap方法赋值到ImageView控件上.

decodeStream最大的秘密在于其直接调用JNIdecodeStream最大的秘密在于其直接调用JNI>>nativeDecodeAsset()来完成decode,无需再使用java层的

createBitmap,从而节省了java层的空间. 

如果在读取时加上图片的Config参数,可以跟有效减少加载的内存,从而跟有效阻止抛out of Memory异常.

另外,decodeStream直接拿的图片来读取字节码了,不会根据机器的各种分辨率来自动适应,使用了decodeStream之后,

需要在hdpi和mdpi,ldpi中配置相应的图片资源,否则在不同分辨率机器上都是同样大小(像素点数量),显示就不正常啦.

解决代码:

     /**     * 以最省内存的方式读取本地资源的图片     * @param context     * @param resId     * @return     */  public static Bitmap readBitMap(Context context, int resId){  BitmapFactory.Options opt = new BitmapFactory.Options();  opt.inPreferredConfig = Config.RGB_565;   opt.inPurgeable = true;  opt.inInputShareable = true;  InputStream is = context.getResources().openRawResource(resId);  return BitmapFactory.decodeStream(is,null,opt);  }
inPurgeable如果设置为true,则由此产生的位图将分配其像素,以便系统需要回收内存时可以将它们清除;

inInputShareable与inPurgeable一起使用,如果inPurgeable为false那该设置将被忽略,如果为true,

那么它可以决定位图是否能够共享一个指向数据源的引用,或者是进行一份拷贝.

的的




0 0
原创粉丝点击