デバイスの画面ロックをオフにするまではうまくいっていましたが、断続的にうまくいかなくなりました。
問題を追跡し、いくつかの回避策を念頭に置いていますが、問題を回避または削除するための「ベスト プラクティス」があるかどうかを知りたいです。
問題:
アプリケーションのステータスに基づいて画像を変更するアプリケーションがあります。画像は巨大ではありませんが、かなり大きく (231k ~)、リソースとして保存されます。画面を数回回転させた後 (1 つの 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) );
}
上記のコードは、問題を再現するために使用した唯一の方法です。
解決を試みながら、サンプルを拡張して、imageView が OnDestry でリリースされるようにしました。
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)
が、これは私が読んだ通常のアクティビティのライフサイクルを壊してしまいますが、これはベストプラクティスではありませんか?
Web を精査したにもかかわらず、同様の問題や例にまだ遭遇していないのは奇妙だと思います。他のほとんどの人がこれにどのように対処しているのか疑問に思っています。
ご意見やご感想をお待ちしております。