Java Android告诉我我的位图在我';我真的回收了它

Java Android告诉我我的位图在我';我真的回收了它,java,android,memory,bitmap,recycle,Java,Android,Memory,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","Testin

我从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;
我第一次运行这段代码时,一切都很好。但是,当我退出应用程序(使用后退键),然后重新启动应用程序时,它可能会工作,也可能不会工作。有时,我会出错:

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

为什么??我甚至还没有回收它。或者更准确地说,它似乎不是在重新创建位图并记住上次的循环

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

同样在安装棒棒糖之前,它工作正常(只要我有bd=null)

我已经连续两天解决这个问题了,如果有人能解释一下,我将不胜感激

编辑

我尝试了@aga的建议,即不要回收/取消bd,但这没有什么区别。重新创建位图后(再次,间歇性地),位图仍然“已经”回收

此外,当这样记录时:

Log.v("NewTag","Backgrounds: "+backgrounds);
我注意到,当它失败时,记录的引用与上次相同。所以


有趣的问题。我很确定,在安卓系统中有一些优化的想法

如果您确实需要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;
 Bitmap backgrounds = BitmapFactory.decodeResource(getResources(), R.drawable.test_image);
或者,您可以首先尝试从标准的
getResources()
获取
Bitmap
,然后才实例化新的资源实例

如果您不需要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;
 Bitmap backgrounds = BitmapFactory.decodeResource(getResources(), R.drawable.test_image);
获取图像和

 backgrounds.recycle();
 backgrounds=null;
回收它


我希望,这会有所帮助。

参考资料类提供了。循环使用
可绘制
位图
时,会破坏缓存的对象。
Resources
缓存无法知道这一点,因此下次您请求该资源时,它们会很高兴地返回相同的对象


当你的应用程序进程死亡时,所有的内存状态都会丢失,包括资源缓存——所以事情会再次工作(一次)。请注意,“退出”应用程序或销毁活动并不一定意味着您的进程将死亡。

正如@snild Dolkow在上文中所述,这种行为的发生是因为位图存储在资源缓存中,当您尝试再次获取它时,您将获得回收的位图

在我看来,解决办法是在必要的时候及时采取行动


此解决方案的开销是,您必须在使用完图像文件后将其删除。

谢谢@KonstantinLoginov,但请参见此(引自问题):“如果我使用BitmapFactory获取位图,则不会发生此问题(遗憾的是,我不能这样做,因为我必须从XML别名获取此特定位图)。”@你还没有想出解决办法?我也有同样的问题。我现在正在删除所有回收代码,并等待回答不幸的是@JayVDiyk,除了你说的不回收位图之外,我从未找到解决方案@我想,我找到了,看看@Jayvdik我想,我找到了,看看!在应用程序关闭前回击是否意味着应用程序已完全关闭?如果按“上一步”,您的活动仍在最近的应用程序下打开?试着把它从那里移走,这样它就应该完全关闭了。@JayVDiyk:不,它没有。在这种情况下,您的
活动将被销毁,但您的进程很可能仍然处于活动状态。安卓将其保留下来,以加速同一应用程序的未来发布。这就是内存统计中所谓的“缓存进程”或“空进程”。系统会根据需要自动清理这些进程。您可以在此处阅读有关流程生命周期的更多信息:@SnildDolkow是否有解决方法?感谢您的回答。我认为“不要回收从
资源
中获取的图像”是您最好的选择。反复重新加载该图像也会带来开销。。。似乎没有必要。