アクティビティでメモリが不足し続ける理由がわかりません。
アクティビティをロードすると、カスタム リストビュー アダプタにロードされる一連の画像があります。アクティビティを開始すると、画面が正常に読み込まれます。しかし、方向を変更したり、戻って再度開始したりすると、アクティビティでメモリ不足の例外が生成されます。
私の活動は次のようになります。
私の活動のコードは次のとおりです。
[Activity(Label = "FishinTales: Fish Species")]
public class Activity_View_FishSpecies : Activity
{
#region Components
private Model n_model;
private ListView n_fishSpeciesListView;
#endregion
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Get Application Global Model
this.n_model = ((MyApp) this.ApplicationContext).FishingData;
// Set our view from the "View_FishSpecies" layout resource
SetContentView(Resource.Layout.View_FishSpecies);
this.n_fishSpeciesListView = FindViewById<ListView> (Resource.Id.xml_fishSpeciesListView);
this.n_fishSpeciesListView.Adapter = new FishSpeciesListAdapter (this.ApplicationContext, this.n_model.SpecieManager.Species);
}
protected override void OnDestroy()
{
base.OnDestroy();
this.unbindDrawables(FindViewById(Resource.Id.xml_root));
this.n_fishSpeciesListView.Adapter = null;
this.n_fishSpeciesListView = null;
}
private void unbindDrawables(View view) {
if (view.Background != null) {
view.Background.SetCallback(null);
}
if (view.GetType() == typeof(ViewGroup)) {
for (int i = 0; i < ((ViewGroup) view).ChildCount; i++) {
unbindDrawables(((ViewGroup) view).GetChildAt(i));
}
((ViewGroup) view).RemoveAllViews();
}
}
}
public class FishSpeciesListAdapter : BaseAdapter
{
Context n_context;
List<AppCode.Specie> n_specieData;
List<Bitmap> n_bitmapCache;
public FishSpeciesListAdapter (Context context, List<AppCode.Specie> specieData)
{
this.n_context = context;
this.n_specieData = specieData;
this.n_bitmapCache = new List<Bitmap>();
this.LoadBitmapsIntoCache();
}
private void LoadBitmapsIntoCache()
{
foreach(AppCode.Specie specie in this.n_specieData)
{
if (specie.RelatedMedia.AttachedPhotos.Count < 1)
{
this.n_bitmapCache.Add(BitmapFactory.DecodeResource(this.n_context.Resources, Resource.Drawable.Icon));
}
else
{
this.n_bitmapCache.Add(BitmapFactory.DecodeByteArray(specie.RelatedMedia.AttachedPhotos[0], 0, specie.RelatedMedia.AttachedPhotos[0].Length));
}
}
}
public override int Count {
get { return this.n_specieData.Count; }
}
public override Java.Lang.Object GetItem (int position)
{
return null;
}
public override long GetItemId (int position)
{
return 0;
}
// create a new ImageView for each item referenced by the Adapter
public override View GetView (int position, View convertView, ViewGroup parent)
{
if(convertView==null){
LayoutInflater li = LayoutInflater.FromContext(parent.Context);
convertView = li.Inflate(Resource.Layout.Adapter_FishSpeciesIcon, null);
}
ImageView iconImage = (ImageView)convertView.FindViewById(Resource.Id.xml_adapter_fishSpeciesIconImage);
TextView nameText = (TextView)convertView.FindViewById(Resource.Id.xml_adapter_fishSpeciesNameText);
TextView scientificNameText = (TextView)convertView.FindViewById(Resource.Id.xml_adapter_fishSpeciesScientificNameText);
nameText.Text = this.n_specieData[position].Name;
scientificNameText.Text = this.n_specieData[position].ScientificName;
iconImage.SetImageBitmap(this.n_bitmapCache[position]);
return convertView;
}
}
OOM エラーが生成されるまでのすべてのプロセスのログを次に示します。
Loading Defaults - Successfully Loaded Defaults
Grow heap (frag case) to 6.474MB for 314670-byte allocation
Clamp target GC heap from 32.512MB to 32.000MB
796824-byte external allocation too large for this process.
VM won't let us allocate 796824 bytes
Clamp target GC heap from 33.447MB to 32.000MB
--- decoder->decode returned false
UNHANDLED EXCEPTION: Java.Lang.OutOfMemoryError: Exception of type 'Java.Lang.OutOfMemoryError' was thrown.
at Android.Runtime.JNIEnv.CallStaticObjectMethod (intptr,intptr,Android.Runtime.JValue[]) <0x00080>
at Android.Graphics.BitmapFactory.DecodeByteArray (byte[],int,int) <0x001bb>
at FishinTales.FishSpeciesListAdapter.LoadBitmapsIntoCache () <0x00187>
at FishinTales.FishSpeciesListAdapter..ctor (Android.Content.Context,System.Collections.Generic.List`1<FishinTales.AppCode.Specie>) <0x000a3>
at FishinTales.Activity_View_FishSpecies.OnCreate (Android.OS.Bundle) <0x0012f>
at Android.App.Activity.n_OnCreate_Landroid_os_Bundle_ (intptr,intptr,intptr) <0x00057>
at (wrapper dynamic-method) object.99ebf5db-74ad-4da9-b431-612691e1f213 (intptr,intptr,intptr) <0x00033>
--- End of managed exception stack trace ---
java.lang.OutOfMemoryError: bitmap size exceeds VM budget(Heap Size=6855KB, Allocated=3089KB, Bitmap Size=26666KB)
at android.graphics.BitmapFactory.nativeDecodeByteArray(Native Method)
at android.graphics.BitmapFactory.decodeByteArray(BitmapFactory.java:625)
at android.graphics.BitmapFactory.decodeByteArray(BitmapFactory.java:638)
at fishintales.Activity_View_FishSpecies.n_onCreate(Native Method)
at fishintales.Activity_View_FishSpecies.onCreate(Activity_View_FishSpecies.java:29)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1093)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1780)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1837)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3242)
at android.app.ActivityThread.access$1600(ActivityThread.java:132)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1037)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:143)
at android.app.ActivityThread.main(ActivityThread.java:4196)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
at dalvik.system.NativeStart.main(Native Method)
Unhandled Exception:
Java.Lang.OutOfMemoryError: Exception of type 'Java.Lang.OutOfMemoryError' was thrown.
at Android.Runtime.JNIEnv.CallStaticObjectMethod (intptr,intptr,Android.Runtime.JValue[]) <0x00080>
at Android.Graphics.BitmapFactory.DecodeByteArray (byte[],int,int) <0x001bb>
at FishinTales.FishSpeciesListAdapter.LoadBitmapsIntoCache () <0x00187>
at FishinTales.FishSpeciesListAdapter..ctor (Android.Content.Context,System.Collections.Generic.List`1<FishinTales.AppCode.Specie>) <0x000a3>
at FishinTales.Activity_View_FishSpecies.OnCreate (Android.OS.Bundle) <0x0012f>
at Android.App.Activity.n_OnCreate_Landroid_os_Bundle_ (intptr,intptr,intptr) <0x00057>
at (wrapper dynamic-method) object.99ebf5db-74ad-4da9-b431-612691e1f213 (intptr,intptr,intptr) <0x00033>
--- End of managed exception stack trace ---
java.lang.OutOfMemoryError: bitmap size exceeds VM budget(Heap Size=6855KB, Allocated=3089KB, Bitmap Size=26666KB)
at android.graphics.BitmapFactory.nativeDecodeByteArray(Native Method)
at android.gra
最初にアクティビティを表示すると、すべて問題ありません。アクティビティを離れて数回戻ってくると、最終的に上記のエラーでクラッシュします。これにより、ビットマップが適切にリサイクルされていないメモリリークが原因でエラーが発生していると推測されます。これらのビットマップを正確に解放する方法の例はありますか? ビットマップが Custom ListView Adapter クラス内にある場合、このトピックに関する情報を見つけるのは困難です。設定後に Bitmap.recycle を配置すると、ListView がリサイクルされたアイテムにアクセスしようとしているという別のエラーが表示されます。上記のコードに従って、どのように/いつリサイクルする必要がありますか。