最近遇到了这个问题:
trying to use a recycled bitmap android.graphics.Bitmap@1d5a0d5c.
于是,写个程序复现这个情况;
public class MainActivity extends AppCompatActivity {
ImageView imageView;
Bitmap bitmap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = (ImageView) findViewById(R.id.iv);
bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.aaa);
imageView.setImageBitmap(bitmap);
try{
if(bitmap!=null&&!bitmap.isRecycled()){
bitmap.recycle();
}
}catch (Exception e){
}
}
public void onClickFinish(View view){
finish();
}
@Override
protected void onDestroy() {
super.onDestroy();
}
}
情景分析:
程序顺序执行,使用图片工厂获取图片后让ImageView显示,即ImageView持有bitmap,此时又继续执行了判断显然bitmap不为空,所以
bitmap调用recycle()方法回收。这就导致一个问题,原来bitmap是归ImageView持有现在回收了,此时ImageView持有一个被回收的数据,所以会报这样的错误。
解决办法:
bitmap什么时间回收呢?这涉及一个回收时机问题
bitmap没有被引用时回收,也就是不再使用。
所以对于一个activity而言,在onDestory()方法中调用 finish方法执行时回收
代码:
@Override
protected void onDestroy() {
super.onDestroy();
if(bitmap!=null&&!bitmap.isRecycled()){
bitmap.recycle();
bitmap = null;
}
}
下面列举我所遇到bitmap回收使用情况:
Bitmap 情况分析:
1.
oldbitmap作为参数传入方法中,然后使用传入bitmap重新生成新的bitmapA
此时
if(bitmapA!=null){
oldbitmap.recycle();
oldbitmap = bitmapA;
}
是正确的。
2.
如果根据res 生成bitmap
此时
Bitmap getBitmap(Bitmap mbitmap) {
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.cccc);
if (bm != null) {
mbitmap.recycle();
mbitmap = bm;
}
return mbitmap;
}
是正确的
3.
传入参数bitmap基础上又形成新的bitmap
Bitmap getBitmap(Bitmap mbitmap) {
Matrix matrix = new Matrix();
matrix.postScale(1, 1); // 长和宽放大缩小的比例
Bitmap resizeBmp = Bitmap.createBitmap(mbitmap, 0, 0, 200, 200, matrix,
false);
if (mbitmap != null) {
mbitmap.recycle();
}
return resizeBmp;
}
此时 正确