Hello Stack Overflow Android Users,
Please help with the following question:
Problem
I'm writing an a feature for an app that lists species of fish. I'm using a custom ListView Adapter class (let's call this FishSpeciesListAdapter) for the adapter. I have 27 fish species recorded as a default for the program as for now (you will eventually be able to add some yourself as well). The problem is that when I link the adapter to the actual listview xml object and scroll down the list, after a while, I get the following error:
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) <0x001db>
at FishinTales.FishSpeciesListAdapter.GetView (int,Android.Views.View,Android.Views.ViewGroup) <0x002f7>
at Android.Widget.BaseAdapter.n_GetView_ILandroid_view_View_Landroid_view_ViewGroup_ (intptr,intptr,int,intptr,intptr) <0x00093>
at (wrapper dynamic-method) object.5dcc133f-a229-41c4-80e2-f5f5260ecdad (intptr,intptr,int,intptr,intptr) <0x0004b>
--- End of managed exception stack trace ---
java.lang.OutOfMemoryError: bitmap size exceeds VM budget
at android.graphics.BitmapFactory.nativeDecodeByteArray(Native Method)
at android.graphics.BitmapFactory.decodeByteArray(BitmapFactory.java:392)
at android.graphics.BitmapFactory.decodeByteArray(BitmapFactory.java:405)
at fishintales.FishSpeciesListAdapter.n_getView(Native Method)
at fishintales.FishSpeciesListAdapter.getView(FishSpeciesListAdapter.java:55)
at android.widget.AbsListView.obtainView(AbsListView.java:1294)
at android.widget.ListView.addViewBelow(ListView.java:2896)
at android.widget.ListView.scrollListItemsBy(ListView.java:2825)
at android.widget.ListView.arrowScrollImpl(ListView.java:2322)
at android.widget.ListView.arrowScroll(ListView.java:2269)
at android.widget.ListView.commonKey(ListView.java:2071)
at android.widget.ListView.onKeyDown(ListView.java:2018)
at android.view.KeyEvent.dispatch(KeyEvent.java:1037)
at android.view.View.dispatchKeyEvent(View.java:3740)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:786)
at android.widget.ListView.dispatchKeyEvent(ListView.java:2003)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:788)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:788)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:788)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:788)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:1667)
at com.android.internal.policy.impl.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1102)
at android.app.Activity.dispatchKeyEvent(Activity.java:2063)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1643)
at android.view.ViewRoot.deliverKeyEventToViewHierarchy(ViewRoot.java:2471)
at android.view.ViewRoot.handleFinishedEvent(ViewRoot.java:2441)
at android.view.ViewRoot.handleMessage(ViewRoot.java:1735)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:4627)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
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) <0x001db>
at FishinTales.FishSpeciesListAdapter.GetView (int,Android.Views.View,Android.Views.ViewGroup) <0x002f7>
at Android.Widget.BaseAdapter.n_GetView_ILandroid_view_View_Landroid_view_ViewGroup_ (intptr,intptr,int,intptr,intptr) <0x00093>
at (wrapper dynamic-method) object.5dcc133f-a229-41c4-80e2-f5f5260ecdad (intptr,intptr,int,intptr,intptr) <0x0004b>
--- End of managed exception stack trace ---
java.lang.OutOfMemoryError: bitmap size exceeds VM budget
at android.graphics.BitmapFactory.nativeDecodeByteArray(Native Method)
at android.graphics.BitmapFactory.decodeByteArray(BitmapFactory.java:392)
at android.graphics.BitmapFactory.decodeByteArray(BitmapFactory.java:405)
at fishintales.FishSpeciesListAdapter.n_getView(Native Met
Here's my Custom ListAdapter:
public class FishSpeciesListAdapter : BaseAdapter
{
Context n_context;
List<AppCode.Specie> n_specieData;
public FishSpeciesListAdapter (Context context, List<AppCode.Specie> specieData)
{
this.n_context = context;
this.n_specieData = specieData;
}
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)
{
View v;
if(convertView==null){
LayoutInflater li = LayoutInflater.FromContext(parent.Context);
v = li.Inflate(Resource.Layout.Adapter_FishSpeciesIcon, null);
}
else
{
v = convertView;
}
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;
if (this.n_specieData[position].RelatedMedia.AttachedPhotos.Count < 1)
{
iconImage.SetImageResource(Resource.Drawable.Icon);
}
else
{
iconImage.SetImageBitmap(BitmapFactory.DecodeByteArray(this.n_specieData[position].RelatedMedia.AttachedPhotos[0], 0, this.n_specieData[position].RelatedMedia.AttachedPhotos[0].Length));
}
return v;
}
}
Other Research On My Behalf
All images are in the range of 100-300KB. Will this really cause this problem?
Please reference my last post for additional code as it is kind of related but needs a new question. Thanks for your time and help.
Solved it!
What it was doing was getting held up on decoding byte arrays into Bitmaps everytime GetView was being called. So what I did was convert them all in the constructor and made a cache of Bitmaps to reference when the GetView method was called.
Here is my updated Custom ListView Adapter that works.
After calling LoadBitmapsIntoCache() in the constructor and saving the Bitmaps to a list. The problem was resolved and I could scroll through all the fish species without any OutOfMemory Errors. Thanks to all who helped.