Android告诉我我的位图在我实际回收之前已经回收了

Zip*_*ppy 3 java memory android bitmap recycle

我从XML获取我的位图:

//Get bitmap from drawable
bd = (BitmapDrawable) view.getResources().getDrawable(R.drawable.backgrounds);
backgrounds = bd.getBitmap();

//Do required work with bitmap (Will just use a log statement here for testing
Log.v("NewTag","Testing: "+bd.getBitmap().getPixel(0, 0));

//Now recycle this large bitmap
bd.getBitmap.recycle();
bd=null;
backgrounds.recycle();
backgrounds=null;
Run Code Online (Sandbox Code Playgroud)

我第一次运行这段代码,一切都很好.但是,当我退出我的应用程序(使用后退键),然后重新启动应用程序,它可能会或可能不会工作.有时,我收到一个错误:

无法在回收的位图上调用getPixel()

为什么?我还没有回收它.或者更确切地说,似乎没有重新创建位图并记住上次回收.

如果我使用BitmapFactory来获取位图,则不会发生此问题(遗憾的是,我不能这样做,因为我必须从XML别名获取此特定位图).

在安装棒棒糖之前,这个工作正常(只要我有bd = null).

我已经连续两天遇到这个问题,所以如果有人能对它发光,我会非常感激.

编辑

我试过@aga建议不要回收/归零bd,但这没什么区别.一旦重新创建(再次,间歇性地),位图仍然"已经"被回收.

此外,当这样记录时:

Log.v("NewTag","Backgrounds: "+backgrounds);
Run Code Online (Sandbox Code Playgroud)

我注意到,当它失败时,记录的引用与前一次相同.所以.....

在此输入图像描述

Sni*_*kow 5

Resources班有从您的APK下载资源高速缓存.当你回收DrawableBitmap,你破坏了缓存的对象.有没有办法让Resources缓存知道这一点,所以他们愉快地你问该资源的下一次您返回相同的对象.

当您的应用程序进程终止时,所有内存状态都将丢失,包括资源缓存 - 因此事情将再次起作用(一次).请注意,"退出"应用程序或销毁活动并不一定意味着您的流程将会死亡.


Kon*_*nov 2

有趣的问题。我很确定,Android 背后有一些优化想法。

如果您确实需要 XML 的位图:

    Resources res = new Resources(getAssets(), new DisplayMetrics(), new Configuration());

    bd = (BitmapDrawable) res.getDrawable(R.drawable.bitmap_drawable);
    backgrounds = bd.getBitmap();

    ......

    bd.getBitmap().recycle();
    bd=null;
    backgrounds.recycle();
    backgrounds=null;
Run Code Online (Sandbox Code Playgroud)

Bitmap或者,您可以首先尝试从标准获取getResources(),然后再实例化新的资源实例。

如果您不需要XML 的位图:

 Bitmap backgrounds = BitmapFactory.decodeResource(getResources(), R.drawable.test_image);
Run Code Online (Sandbox Code Playgroud)

获取图像和

 backgrounds.recycle();
 backgrounds=null;
Run Code Online (Sandbox Code Playgroud)

回收它。

我希望,它有帮助。