-
概况:
这个课程给出了处理和加载bitmap的通用技术,能让UI线程不会阻塞,同时防止出现java.lang.OutofMemoryError: bitmap size exceeds VM budget.
- 原因:
A 在Android兼容性定义文档(CDD)3.7章节中,移动设备对单个应用所需的最小内存做了规定。然而,请记住许多设备都被设置了更高的内存限制。
B 单张图片就常常占用了大量的空间。
C 很多应用或控件,像ListView,GridView和ViewPager等包含了很多图片。
- 从图片的四个阶段(加载,处理,缓存,显示)给出了具体方法:
A 加载:先只是读取图片的总体信息(BitmapFactory.Options.inJustDecodeBounds = true;),再根据需要读取的数据信息(simapleSize),下面的算法就算采样率。
public static int calculateInSampleSize( BitmapFactory.Options options, int reqWidth, int reqHeight) { // Raw height and width of image final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { // Calculate ratios of height and width to requested height and width final int heightRatio = Math.round((float) height / (float) reqHeight); final int widthRatio = Math.round((float) width / (float) reqWidth); // Choose the smallest ratio as inSampleSize value, this will guarantee // a final image with both dimensions larger than or equal to the // requested height and width. inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; } return inSampleSize; }
B 处理:不在主线程处理图片,包括这些操作:从网络或硬盘读出,对图片的缩放变换处理。
C 缓存:使用内存缓存(LruCache)和硬盘缓存(DiskLruCache),用放在内存中的Fragment(setRetainInstance(true))解决系统配置发生变化之后是缓存。
D 显示.
补充通过:Runtime.getRuntime().maxMemory()
-
android 各个版本对于bitmap管理的不同:
A 2.2及其之前会延迟回收,而2.3以后是只要没有引用就及时回收。
B 2.3.3及其以前,bitmap的像素信息存在native memory。3.0之后是放在java heap。
2.3.3及其之前用recycle,之后用BitmapFactory.Options.inBitmap
-
参考:http://developer.android.com/training/displaying-bitmaps/index.html