1

so Im trying to make an app that when you click on a button, it displays a lot of images. The problem is that when I click the button, the application crashes. Here is a part of my XML file. It has 36 different images:

<ImageView android:id="@+id/imageView31" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:src="@drawable/veh1" /> <ImageView android:id="@+id/imageView32" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:src="@drawable/veh2" /> <ImageView android:id="@+id/imageView33" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:src="@drawable/veh3" /> 

...

And here is the LogCat:

02-18 22:47:00.263: E/AndroidRuntime(366): FATAL EXCEPTION: main 02-18 22:47:00.263: E/AndroidRuntime(366): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.guzi.samphelptools/com.guzi.samphelptools.Vehicles}: android.view.InflateException: Binary XML file line #81: Error inflating class <unknown> 02-18 22:47:00.263: E/AndroidRuntime(366): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647) 02-18 22:47:00.263: E/AndroidRuntime(366): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663) 02-18 22:47:00.263: E/AndroidRuntime(366): at android.app.ActivityThread.access$1500(ActivityThread.java:117) 02-18 22:47:00.263: E/AndroidRuntime(366): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931) 02-18 22:47:00.263: E/AndroidRuntime(366): at android.os.Handler.dispatchMessage(Handler.java:99) 02-18 22:47:00.263: E/AndroidRuntime(366): at android.os.Looper.loop(Looper.java:130) 02-18 22:47:00.263: E/AndroidRuntime(366): at android.app.ActivityThread.main(ActivityThread.java:3683) 02-18 22:47:00.263: E/AndroidRuntime(366): at java.lang.reflect.Method.invokeNative(Native Method) 02-18 22:47:00.263: E/AndroidRuntime(366): at java.lang.reflect.Method.invoke(Method.java:507) 02-18 22:47:00.263: E/AndroidRuntime(366): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) 02-18 22:47:00.263: E/AndroidRuntime(366): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) 02-18 22:47:00.263: E/AndroidRuntime(366): at dalvik.system.NativeStart.main(Native Method) 02-18 22:47:00.263: E/AndroidRuntime(366): Caused by: android.view.InflateException: Binary XML file line #81: Error inflating class <unknown> 02-18 22:47:00.263: E/AndroidRuntime(366): at android.view.LayoutInflater.createView(LayoutInflater.java:518) 02-18 22:47:00.263: E/AndroidRuntime(366): at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56) 02-18 22:47:00.263: E/AndroidRuntime(366): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:568) 02-18 22:47:00.263: E/AndroidRuntime(366): at android.view.LayoutInflater.rInflate(LayoutInflater.java:623) 02-18 22:47:00.263: E/AndroidRuntime(366): at android.view.LayoutInflater.rInflate(LayoutInflater.java:626) 02-18 22:47:00.263: E/AndroidRuntime(366): at android.view.LayoutInflater.rInflate(LayoutInflater.java:626) 02-18 22:47:00.263: E/AndroidRuntime(366): at android.view.LayoutInflater.inflate(LayoutInflater.java:408) 02-18 22:47:00.263: E/AndroidRuntime(366): at android.view.LayoutInflater.inflate(LayoutInflater.java:320) 02-18 22:47:00.263: E/AndroidRuntime(366): at android.view.LayoutInflater.inflate(LayoutInflater.java:276) 02-18 22:47:00.263: E/AndroidRuntime(366): at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:207) 02-18 22:47:00.263: E/AndroidRuntime(366): at android.app.Activity.setContentView(Activity.java:1657) 02-18 22:47:00.263: E/AndroidRuntime(366): at com.guzi.samphelptools.Vehicles.onCreate(Vehicles.java:14) 02-18 22:47:00.263: E/AndroidRuntime(366): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 02-18 22:47:00.263: E/AndroidRuntime(366): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611) 02-18 22:47:00.263: E/AndroidRuntime(366): ... 11 more 02-18 22:47:00.263: E/AndroidRuntime(366): Caused by: java.lang.reflect.InvocationTargetException 02-18 22:47:00.263: E/AndroidRuntime(366): at java.lang.reflect.Constructor.constructNative(Native Method) 02-18 22:47:00.263: E/AndroidRuntime(366): at java.lang.reflect.Constructor.newInstance(Constructor.java:415) 02-18 22:47:00.263: E/AndroidRuntime(366): at android.view.LayoutInflater.createView(LayoutInflater.java:505) 02-18 22:47:00.263: E/AndroidRuntime(366): ... 24 more 02-18 22:47:00.263: E/AndroidRuntime(366): Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget 02-18 22:47:00.263: E/AndroidRuntime(366): at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method) 02-18 22:47:00.263: E/AndroidRuntime(366): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:460) 02-18 22:47:00.263: E/AndroidRuntime(366): at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:336) 02-18 22:47:00.263: E/AndroidRuntime(366): at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:697) 02-18 22:47:00.263: E/AndroidRuntime(366): at android.content.res.Res`enter code here`ources.loadDrawable(Resources.java:1709) 02-18 22:47:00.263: E/AndroidRuntime(366): at android.content.res.TypedArray.getDrawable(TypedArray.java:601) 02-18 22:47:00.263: E/AndroidRuntime(366): at android.widget.ImageView.<init>(ImageView.java:118) 02-18 22:47:00.263: E/AndroidRuntime(366): at android.widget.ImageView.<init>(ImageView.java:108) 02-18 22:47:00.263: E/AndroidRuntime(366): ... 27 more 

Okay, so I found this simple listview thing, but i cant get it running.

 import android.os.Bundle; import android.app.Activity; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import android.widget.ListView; import android.widget.SimpleAdapter; public class MainActivity extends Activity { // Array of integers points to images stored in /res/drawable-hdpi/ int[] vehs = new int[]{ R.drawable.veh1, R.drawable.veh2, R.drawable.veh3, R.drawable.veh4, R.drawable.veh5, R.drawable.veh6, R.drawable.veh7, R.drawable.veh8, R.drawable.veh9, R.drawable.veh10, R.drawable.veh11, R.drawable.veh12, R.drawable.veh13, R.drawable.veh14, R.drawable.veh15, R.drawable.veh16, R.drawable.veh17, R.drawable.veh18, R.drawable.veh19, R.drawable.veh20, R.drawable.veh21, R.drawable.veh22, R.drawable.veh23, R.drawable.veh24, R.drawable.veh25, R.drawable.veh26, R.drawable.veh27, R.drawable.veh28, R.drawable.veh29, R.drawable.veh30, R.drawable.veh31, R.drawable.veh32, R.drawable.veh33, R.drawable.veh34, R.drawable.veh35, R.drawable.veh36, }; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Each row in the list stores country name, currency and flag List<HashMap<String,String>> aList = new ArrayList<HashMap<String,String>>(); for(int i=0;i<10;i++){ HashMap<String, String> hm = new HashMap<String,String>(); hm.put("", Integer.toString(vehs[i]) ); aList.add(hm); } // Keys used in Hashmap String[] from = { "flag","txt","cur" }; // Ids of views in listview_layout int[] to = { R.id.vehs}; // Instantiating an adapter to store each items // R.layout.listview_layout defines the layout of each item SimpleAdapter adapter = new SimpleAdapter(getBaseContext(), aList, R.layout.listview_layout, from, to); // Getting a reference to listview of main.xml layout file ListView listView = ( ListView ) findViewById(R.id.listview); // Setting the adapter to the listView listView.setAdapter(adapter); } } 

If you could help me with this, that would be great! :D

3
  • Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget or in other words too many/big images Commented Feb 18, 2014 at 23:00
  • @donfuxx is there a way of fixing this? Or i just cant put many images? Commented Feb 18, 2014 at 23:15
  • 36 images is a lot of images for one layout.. try loading fewer img first Commented Feb 18, 2014 at 23:19

1 Answer 1

2

The problem you have here is you are loading everything at the same time, I guess. You should try using a ListView and inflate each row! The way this would work is that your app will load an ImageView or two at once and the rest will be left on the side, until the user scrolls close to it.

The tutorial I found for this is (watch #71 to about #87 - you can get all his videos at slidenerd.com):
http://www.youtube.com/watch?v=uic3TVp_j3M#t=0

You should also resize your bitmaps so they aren't loaded in full resolution. You don't need a 1920x1080 image for a 540*420 screen, for example. The following link shows you how to take care of this. http://developer.android.com/training/displaying-bitmaps/index.html

So, in the end, you will have only 1 ListView, 1 ImageView and way less code and way less confusion :P

EDIT: QUICK GUIDE: I'll walk you through the ListView method only, because I think the scaling down of an image example by Google is easy to follow.

So, first of all, you will have the following:

  1. myActivity.xml (the main Activity where you need these images)
  2. Single row (the layout of what a single row looks like)
  3. MyActivity.java (The java class for your activity)

myActivity.xml will contain a ListView:

<ListView android:id="@+id/lvList" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" > </ListView> 

singleRow.xml will contain just an ImageView - you will use the same ImageView's LayoutParamaters and mirror them 36 times:

<ImageView android:id="@+id/ivImage" android:layout_width="50dp" android:layout_height="85dp" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:src="@drawable/ic_launcher" /> 

MyActivity.java - where all the magic happens!

public class MyActivity extends Activity implements OnItemClickListener { ListView lv; @Override protected void onCreate(Bundle savedInstanceState) { lv = (ListView) findViewById(R.id.lvList); MyAdapter adapter = new MyAdapter(this); lv.setAdapter(adapter); lv.setOnItemClickListener(this); } @Override public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { MyView holder = (MyView) view.getTag(); // This will get the tag of the item click - that is set up below } //Create a holder for the image that will be in an ImageView class SingleRowData { int img; SingleRowData(int img) { this.img = img; } } //A reference to the ImageView that needs to be copied private class MyView { ImageView ivImg; MyView(View v) { ivImg = (ImageView) v.findViewById(R.id.ivHomePageRow); } } class MyAdapter extends BaseAdapter{ ArrayList<SingleHPSRow> list; Context context; public MyAdapter(Context context) { this.context = context; list = new ArrayList<SingleRowData>(); ... int[] imgId = ...; // let's say you are getting all the images from your resources .. you will have to set this up, I'm guessing you know how to. for(int item = 0; item < imgUrl.length; i++) { list.add(imgId[item]); } } @Override public int getCount() { return list.size(); } @Override public Object getItem(int position) { return list.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { view row = convertView; //This will try to see if the row has already been loaded b4 MyView holder = null; initialize our custome View for the row if(row == null) { // new row LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); //Get the LayoutInflater row = inflater.inflate(R.layout.singleRow, parent, false); //Reference to the row layout holder = new MyView(row); row.setTag(holder); // Give the row a tag - the holder that contains the item } else { // old row holder = (MyView) row.getTag(); //Get the tag that was assigned } SingleRowData item = list.get(position); //Get the item at the current position int image = item.img; //Get the imgId assigned to the current item holder.ivImg.setImageResource(image); //Load image for the current position return row; // Return the current row } } } 

Hopefull this is well explained, I copied and shortened one of my codes. Let me know if there's something you don't understand

Sign up to request clarification or add additional context in comments.

12 Comments

Will try this out! Thanks for the fast reply
No problem. I had the same problem when i started. But after listening to slideNerd, my apps are less laggy. On my most recent app, I've a ListView with 144 images being loaded without any ui lag ! He is a bit loud though. lol
I know right! He doesn't stop talking xD. Im trying to guess what he's talking about haha.
Is there a way you can show me some of your code? I just need to display 36 images in a layout... And i dont really want to watch those videos. They seem confusing
I'll edit the code to give you a quick walkthrough. Eating right now though, give me like 15 minutes.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.