Android如何最优化的读取一张Bitmap

来源:互联网 发布:淘宝怎么开通直播 编辑:程序博客网 时间:2024/06/01 23:57
Drawable缓存问题,显示清晰度,

Resource.getDrawable会根据ID返回Drawable,然后把这个Drawable缓存起来,看以下这个代码段:
[java] view plaincopy
  1. InputStream is = mAssets.openNonAsset(  
  2.                                 value.assetCookie, file, AssetManager.ACCESS_STREAMING);  
  3.         //                System.out.println("Opened file " + file + ": " + is);  
  4.                         dr = Drawable.createFromResourceStream(this, value, is,  
  5.                                 file, null);  
  6.                         is.close();  

[java] view plaincopy
  1. dr.setChangingConfigurations(value.changingConfigurations);  
  2.             cs = dr.getConstantState();  
  3.             if (cs != null) {  
  4.                 if (mPreloading) {  
  5.                     sPreloadedDrawables.put(key, cs);  
  6.                 } else {  
  7.                     synchronized (mTmpValue) {  
  8.                         //Log.i(TAG, "Saving cached drawable @ #" +  
  9.                         //        Integer.toHexString(key.intValue())  
  10.                         //        + " in " + this + ": " + cs);  
  11.                         mDrawableCache.put(key, new WeakReference<Drawable.ConstantState>(cs));  
  12.                     }  
  13.                 }  
  14.             }  

缓存机制设计的很好,使用了弱引用机制避免内存溢出。但这个方法比较老实,如果资源是一张Bitmap的话,原图是多大,它就会生成多大的。为了让程序在不同的屏幕上面都比较清晰,并且图片占用内存不会过大,通常会根据不同的屏幕选择加载不同的图,但这样包大小又上去了,一般,我们会用到这样一个解决办法:

只放一张最大清晰度的图,程序运行时根据当前屏幕尺寸对图片进行缩放。

这个办法有一个缺点,就是加载时会先加载一张大图,再根据大图去生成小图,内存峰值是两张图,在内存紧张的手机上有什么办法么?下面是解决方案:

[java] view plaincopy
  1. private BitmapDrawable getDrawable(int id) {  
  2.         int width = AppTools.getSreenSize(thistrue);  
  3.         int height = AppTools.getSreenSize(thisfalse);  
  4.         BitmapFactory.Options opts = new BitmapFactory.Options();  
  5.         opts.inJustDecodeBounds = true;  
  6.         BitmapFactory.decodeResource(getResources(), id, opts);  
  7.         opts.inSampleSize = AppTools.computeSampleSize(opts, -1,  
  8.                 (int) (width * height));  
  9.         opts.inJustDecodeBounds = false;  
  10.         Bitmap bitmap = null;  
  11.         try {  
  12.             bitmap = BitmapFactory.decodeResource(getResources(), id, opts);  
  13.         } catch (OutOfMemoryError e) {  
  14.         }  
  15.         if (bitmap == null) {  
  16.             return null;  
  17.         }  
  18.         return new BitmapDrawable(bitmap);  
  19.   
  20.     }  
先使用获取图片的宽高,然后根据目标宽高计算出采样大小,最后再真正读取图片。

[java] view plaincopy
  1. BitmapFactory.Options opts = new BitmapFactory.Options();  
  2.         opts.inJustDecodeBounds = true;  
  3.         BitmapFactory.decodeResource(getResources(), id, opts);  
0 0
原创粉丝点击