一、背景
贝壳2.6.0版本使用Glide preload方法替换了部分显示图片的方式, 在灰度期间发现控件显示了错误的图片或者崩溃问题。
Fatal Exception: java.lang.RuntimeException:Canvas: trying to use a recycled bitmap android.graphics.Bitmap@25e89bf at android.graphics.Canvas.throwIfCannotDraw(Canvas.java:1271) at android.view.DisplayListCanvas.throwIfCannotDraw(DisplayListCanvas.java:257) at android.graphics.Canvas.drawBitmap(Canvas.java:1415) at com.bumptech.glide.load.resource.bitmap.GlideBitmapDrawable.draw(GlideBitmapDrawable.java:101)
二、原因分析
Glide使用activityResources、LruResourceCache、LruBitmapPool等3级内存和文件缓存LazyDiskCacheProvider。
activeResources是个Map, key值(EngineKey)根据10个参数组合生成,value是ResourceWeakReference类型; resource是EngineResource类并实现引用计数。
activeResources.put(key, new ResourceWeakReference(key, resource, getReferenceQueue()));
public void recycle() {
if (acquired > 0) {
throw new IllegalStateException("Cannot recycle a resource while it is still acquired");
}
if (isRecycled) {
throw new IllegalStateException("Cannot recycle a resource that has already been recycled");
}
isRecycled = true;
resource.recycle(); //实际上将Bitmap添加到BitmapPool
}
/**
* Increments the number of consumers using the wrapped resource. Must be called on the main thread.
*
* <p>
* This must be called with a number corresponding to the number of new consumers each time new consumers
* begin using the wrapped resource.