我似乎无法弄清楚为什么我的活动内存不足。
当我加载活动时,我有一堆图像被加载到自定义列表视图适配器中。当我开始活动时,屏幕加载正常。但是当我改变方向或返回并再次启动时,活动会生成内存不足异常。
以下是我的活动:
以下是我的活动代码:
[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正在尝试访问回收的项目。那么我应该如何/何时根据上面的代码进行回收。
答案 0 :(得分:1)
我想知道您使用的是哪个版本的Android。如果是Jelly Bean(Android 4.1.1),请删除此行代码
this.n_bitmapCache.Add(BitmapFactory.DecodeResource(this.n_context.Resources, Resource.Drawable.Icon));
并查看是否有内存泄漏。
我的应用程序在Android 4.1.1更新后也开始出现内存泄漏,我发现问题在
setBackgroundResource(id);
我尝试将其更改为
setBackground(context.getResources().getDrawable(id));
但仍然是内存泄漏。我想确认是否是我的代码中的错误或Jelly Bean中的错误,如果我们尝试从Resources创建drawables或bitmaps,则会导致内存泄漏。 抱歉没有回答你的问题,但我们至少可以知道错误的原因并提出Android团队的问题。
<强>更新强> 我在link
中找到了解决方案请对从资源的drawable文件夹创建的位图使用setBackgroundDrawable(null)。