我正在开发一个应用程序来实例化一堆位图对象(例如按钮,它们具有缓存位图,因此它们不必一次又一次地渲染)
现在,我意识到当我在huawei移动设备上反复运行和启动应用程序时,我会在应用程序尝试为位图分配一些内存时获得OutOfMemoryException。 所以我猜这是制造麻烦的位图。我知道有一个bitmap.recycle()方法。
现在我的问题是:清理记忆的最佳做法是什么? 为什么没有像View :: onDestroy()这样的View方法可以实现清理目的?
编辑:示例
我的“CirclyButton”(extends Button)类总是在onDraw上绘制一个缓存的位图:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap(this.getDefaultBitmap(), 0, 0, paint);
}
private Bitmap getDefaultBitmap(){
if(mBitmapDefault == null){
mBitmapDefault = Bitmap.createBitmap(8*radius, 8*radius, Config.ARGB_8888);
Canvas canvas = new Canvas(mBitmapDefault);
this.drawDefault(canvas);
return mBitmapDefault;
}
return mBitmapDefault;
}
所以我猜这个分配的数据应该在某个地方回收......?
答案 0 :(得分:2)
视图没有onDestroy
方法,因为视图通常不会被销毁,活动也会如此。如果活动没有发生任何事情,那么视图就不会被破坏(除非你膨胀不同的布局......事实并非如此,对吧?),如果它的活动发生了什么,你的回调就会被调用。 / p>
如果有recycle()
方法,请务必调用它。并删除所有对内存中引用onDestroy
中对象的引用,即:
@Override
public void onDestroy() {
object1 = null;
object2 = null;
//...
}
所以GC可以完成它的工作。我对AdMob的AdView
遇到了同样的问题,尽管他们确实使用了destroy
方法,但实际上并没有帮助。但删除我对视图的引用可以解决问题。
答案 1 :(得分:1)
提供有关您使用位图的位置的更多信息,我有一些处理图像和节省内存的丰富经验。
例如在我的应用程序中,我有一些数据列表,每行显示一些位图。我将我的列表存储在一个片段中(对于片段支持我使用兼容性库),我在这个片段onDestroy方法上回收了我的位图。
后来我决定优化我的列表,所以我将滚动监听器添加到我的列表中,并在它们从屏幕上滚动时开始回收位图。