Android中如何彻底清除Bitmap内存?静态变量赋值后跳转报错求助
嘿,我来帮你拆解下你遇到的这个问题:
你现在的核心问题出在对Bitmap.recycle()的理解上。当你调用这个方法时,它会释放Bitmap底层的原生像素内存,但Java层的Bitmap对象本身并没有被垃圾回收掉——它还好好待在静态变量StaticVeriables.getScannedFromGallery里,只是变成了一个“空壳”,没有可用的像素数据了。
为什么不跳转页面就没事?因为那段代码里没人去碰这个已经被“掏空”的Bitmap。但一旦你跳转到EditImage页面,这个页面肯定会尝试去使用静态变量里的这个Bitmap(比如显示到ImageView、做编辑操作),这时候调用任何需要像素数据的方法,自然就会抛出异常了。
给你几个可行的解决方案:
方案1:直接去掉recycle()调用
既然你后续还要在新页面使用这个Bitmap,完全没必要提前调用recycle()。Android的垃圾回收机制会在内存紧张的时候自动处理Bitmap的底层资源,或者等静态变量不再被引用时释放内存。修改后的代码如下:
StaticVeriables.getScannedFromGallery = bitmap; Intent gallery1 = new Intent(MainActivity.this, EditImage.class); gallery1.putExtra("isGallery",true); startActivity(gallery1); finish();
方案2:在使用完Bitmap后再回收
如果你担心内存占用过高,可以把recycle()的操作放到EditImage页面里,等你彻底不需要这个Bitmap的时候再执行。比如在页面销毁或者编辑完成后:
// 在EditImage页面的onDestroy方法或者编辑完成的回调里 if (StaticVeriables.getScannedFromGallery != null && !StaticVeriables.getScannedFromGallery.isRecycled()) { StaticVeriables.getScannedFromGallery.recycle(); StaticVeriables.getScannedFromGallery = null; // 顺便把静态变量置空,帮GC更快回收 }
方案3:别用静态变量传Bitmap(更推荐)
用静态变量持有Bitmap很容易踩内存泄漏的坑,尤其是当页面销毁后静态变量还攥着引用不放的时候。换个更稳妥的方式传递Bitmap吧:
- 用Intent直接传:Bitmap实现了Parcelable接口,能直接放到Intent里传递(注意:太大的Bitmap可能会触发
TransactionTooLargeException,如果是超大图建议先压缩) - 存临时文件:把Bitmap保存到本地临时文件,新页面读取文件生成Bitmap
- 用内存缓存:比如用LruCache存储Bitmap,新页面通过key获取
举个Intent传递的例子:
// MainActivity里的代码 Intent gallery1 = new Intent(MainActivity.this, EditImage.class); gallery1.putExtra("isGallery", true); gallery1.putExtra("scannedBitmap", bitmap); // 直接把Bitmap塞进去 startActivity(gallery1); finish(); // EditImage里获取Bitmap Bitmap bitmap = getIntent().getParcelableExtra("scannedBitmap");
最后提醒下:如果一定要用静态变量,记得在不需要的时候及时置空并回收,既避免内存泄漏,也不会出现这种“空壳Bitmap”的问题;处理大Bitmap时,记得先做压缩,不然很容易触发OOM哦~
内容的提问来源于stack exchange,提问作者emrekocaman

