事情进展顺利,直到我关闭设备上的屏幕锁定,然后事情开始间歇性地出错。
我已经设法追踪问题并考虑了一些解决方法,但我想知道是否有避免或消除问题的“最佳实践”。
问题:
我有一个应用程序可以根据应用程序状态更改图像。图像不是很大,但相当大(231k~),并作为资源存储。经过几次屏幕旋转(我在使用单个 ImageView 的项目中计算了 27 次),加载图像失败,出现“Java.Lang.OutOfMemoryError”类型的异常
剥离到最简单的项目,以下演示了该问题:
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
// Set our view from the "main" layout resource
SetContentView (Resource.Layout.Main);
//get a reference to the ImageView
var imageView = FindViewById<ImageView>(Resource.Id.imageView1);
imageView.SetImageBitmap( Android.Graphics.BitmapFactory.DecodeResource( this.Resources, Resource.Drawable.Ready) );
}
上面的代码是我用来重现该问题的唯一方法。
在尝试解决的同时,我扩展了示例,以便在 OnDestry 中发布 imageView:
protected override void OnDestroy ()
{
base.OnDestroy ();
imageView.SetImageBitmap( null );
imageView.DestroyDrawingCache();
imageView.Dispose();
}
除非我添加了我不想做的 GC.Collect() ,否则这没有什么区别。
到目前为止,我目前想到的最好的解决方法是修改代码如下:
static Bitmap _ready = null;
private Bitmap GetReadyImage {
get {
if (_ready == null) {
_ready = Android.Graphics.BitmapFactory.DecodeResource (this.Resources, Resource.Drawable.Ready);
}
return _ready;
}
}
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
// Set our view from the "main" layout resource
SetContentView (Resource.Layout.Main);
//get a reference to the ImageView
imageView = FindViewById<ImageView>(Resource.Id.imageView1);
imageView.SetImageBitmap( GetReadyImage );
}
这依赖于对每个位图的静态引用和每个位图的属性访问器。
我什至可以编写一个将图像存储在静态列表中的方法,以保存为每个不同的属性/变量编写属性访问器。
我也许可以添加标志ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize |ConfigChanges.KeyboardHidden)
,但这会破坏我读过的正常活动生命周期不是最佳实践吗?
我觉得很奇怪,在网上搜索过,我还没有遇到过类似的问题或例子。我想知道大多数其他人如何处理这个问题?
非常感谢任何想法或评论。