Android Bitmap内存管理,解决内存溢出问题(1)之自定义BitmapDrawable
来源:互联网 发布:淘宝买二手怎么交易 编辑:程序博客网 时间:2024/05/16 09:39
在Android 2.3.3或者更低版本下的时候,对于释放Bitmap的内存调用recycle()方法是必要的。否则在加载大量Bitmap的时候很容易就造成 OutOfMemoryError
。recycle()能够及时的释放Bitmap内存。
注意:只有在不用Bitmap的时候才能调用recycle(),否则会造成Canvas: trying to use a recycled bitmap问题。
内存管理的全部实现有点复杂,但是把复杂的问题拆分开来作就非常简单了,在本章中只是实现能够自己释放内存的
BitmapDrawable。代码如下:
public static final StringTAG= "RecyclingBitmapDrawable";/** * 正在使用(显示)的计数 * */private intmDisplayRefCounts= 0;/** * 正在被缓存的计数 * */private intmCacheRefCounts= 0;/** * 是否已经被显示过了 * */private booleanmHasDisplay= false;public RecyclingBitmapDrawable(Resources res, Bitmap bitmap) {super(res, bitmap);// TODO Auto-generated constructor stub}/** * * 设置BitmapDrawable是否正在显示,如果显示这里传入true,如果不再显示了这里传入 false * * @param isDisplayed * 是否显示 * */public void setIsDisplayed(boolean isDisplayed) {synchronized (this) { // 保持同步,防止多个线程修改数据时造成 Canvas: trying to use a// recycled bitmap或者 OutOfMemoryErrorif (isDisplayed) {mDisplayRefCounts++;mHasDisplay = true;} else {mDisplayRefCounts--;}}// 这个不需要同步checkState();}/** * 设置BitmapDrawable是否正在被缓存,如果被缓存了这里传入true,否则传入 false * */public void setIsCached(boolean isCached) {synchronized (this) {if (isCached) {mCacheRefCounts++;} else {mCacheRefCounts--;}}checkState();}// 检测显示和缓存状态,如果计数都为0的话,就释放Bitmapprivate void checkState() {synchronized (this) {if (mDisplayRefCounts <= 0 && mCacheRefCounts <= 0 && mHasDisplay && hasVildBitmap()) {if (BuildConfig.DEBUG) {System.out.println(TAG + "--" + "释放不再使用的Bitmap");getBitmap().recycle();}}}}// 检测Bitmap是否可用,Bitmap不能为空,并且没有被释放private boolean hasVildBitmap() {synchronized (this) {Bitmap bitmap = getBitmap();return bitmap != null && !bitmap.isRecycled();}}
用 BitmapFactory.Options.inBitmap
这个字段,具体内容查看http://blog.csdn.net/hello_tree/article/details/11732293
在这里总结下android不同版本对于图片存储和释放的不同之处:
①在过去通过 SoftReference或者WeakReference来缓存Bitmap,但是从Android 2.3(API Level 9)开始,就不推荐
使用了,因为从2.3开始垃圾回收器会非常积极的回收 soft/weak 引用,这使得这样缓存相当无效。
②在Android3.0(API Level 11)之前,bitmap的像素数据是存储在 in native memory 本地的,是和Bitmap自己分
开存储的,Bitmap存储在 Dalvik heap中,Bitmap的像素数据(在 native memeory中)的释放是不可预见的,这
可能导致程序内存不够从而崩溃。在Android 3.0(API Level 11)开始,Bitmap的像素数据和相关的Bitmap一块存储
在 Dalvik heap中。
③在Android 3.0(API Level 11)之前,如果加载大量bitmap数据在你的app 中时,应该在不用Bitmap的时候调用
recycle()方法,recycle()方法允许app尽快的回收内存(由于在 3.0之前Bitmap的后台像素数据和Bitmap是分开存
储的,并且后台数据的释放是不可预见的,所以通过手动调用Bitmap的recycle()方法来释放内存)。
④在Android 3.0(API Level 11)和之后的版本中,由于bitmap的后台像素数据和它本身一块存储在虚拟机堆(Dalvik
heap)中,所
以不用手动调用Bitmap的recycle()方法,当没有引用指向Bitmap的时候,垃圾回收器会自动释放bitmap的内存。
- Android Bitmap内存管理,解决内存溢出问题(1)之自定义BitmapDrawable
- 解决Android Bitmap内存溢出问题
- android解决bitmap内存溢出之二
- android之Bitmap内存溢出
- android Bitmap过大内存溢出问题的解决
- android中使用SoftRefrence解决Bitmap过大内存溢出问题
- android中使用SoftRefrence解决Bitmap过大内存溢出问题
- 解决读取bitmap内存溢出问题
- 解决Bitmap导致的内存溢出问题
- Bitmap内存溢出问题
- android bitmap内存溢出
- Android bitmap 内存溢出
- android bitmap内存溢出
- Android Bitmap内存溢出
- Android Bitmap内存溢出
- android Bitmap内存溢出
- Android Bitmap 内存溢出的问题
- Android解决内存溢出问题
- 密码生成器
- weblogic11R1在64位win7和64位JVM下的问题
- <JAVA>手动触发StackOverflowError异常
- ORACLE用户、角色、权限
- 未能加载文件或程序集“System.Data.SQLite ??
- Android Bitmap内存管理,解决内存溢出问题(1)之自定义BitmapDrawable
- 优秀操盘手:一个品行端方的群体
- Gabow算法
- init.rc翻译
- 流与文件
- 圆形头像的做法
- MapReduce Design Patterns-chapter 6
- IOS用CGContextRef画各种图形(文字、圆、直线、弧线、矩形、扇形、椭圆、三角形、圆角矩形、贝塞尔曲线、图片)
- 网络营销 实战才能得出真理