0

I have an app that displays 4 ImageViews in the Activity. I store all the possible images in the res/drawable folder. The images are all .png that can range anywhere from 5KB - 22KB and are all are 300x300 pixels. The images get set to in a method like so:

private void displayChoices() {
    iv1.setImageResource(mArrayList.get(0)
            .getResourceId(this));
    iv2.setImageResource(mArrayList.get(1)
            .getResourceId(this)); // <--Usually fails on second image.
    iv3.setImageResource(mArrayList.get(2)
            .getResourceId(this));
    iv4.setImageResource(mArrayList.get(3)
            .getResourceId(this));
}

The displayChoices() method is called multiple times throughout the session. So far I've read through Displaying Bitmaps Efficiently, but trying to scale down the resolution of the images makes them grainy.

mArrayList is an ArrayList of an object. Within the object class I have a method called getResourceId.

 public int getResourceId(Context ctx) {
    int mResId;
    String packageName = ctx.getPackageName();
    String mDrawableName = filename.substring(0, filename.lastIndexOf('.')); //filename is stored in the database and is set when I create the object. it is just a reference to the an .png file in the resource folder.

    mResId =  ctx.getResources().getIdentifier(mDrawableName , "drawable", packageName);

    return mResId;
}

The images are displayed in a 2x2 grid that is evenly distributed on the screen.

 <LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:baselineAligned="false"
    android:orientation="horizontal" > 
    <FrameLayout
        android:id="@+id/choice_1_frame"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:padding="5dip" >

        <ImageView
            android:id="@+id/choice_1_image"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_gravity="center"
            android:adjustViewBounds="true"
            android:src="@drawable/test_image300x300" />
    </FrameLayout>
    //repeat frame layout
 </LinearLayout>
 //Repeat LinearLayout

I've tried to clear reference to old images when the method is called each time but it fails on the first call so I'm lost right now. Any ideas on how to stop the OutOfMemory Exceptions from occuring.

Woodsy
  • 3,177
  • 2
  • 26
  • 50
  • This link my help you http://stackoverflow.com/questions/477572/android-strange-out-of-memory-issue-while-loading-an-image-to-a-bitmap-object/823966#823966 – Sruit A.Suk Aug 10 '12 at 18:51
  • Are you storing (int) ids of images in the array list??? – Harpreet Aug 10 '12 at 18:53
  • Why do you need to load the images in code? You could just do it in XML layout files. Anyway, we'll probably need more code to fix this for you. – Michell Bak Aug 10 '12 at 18:55
  • @Haps I added some additional code that shows the what mArrayList.get(0).getResourceId(this) is calling. – Woodsy Aug 10 '12 at 19:03
  • @MichellBak The app works like a quiz where the user is give 4 pictures to choose from. The images will change depending on the question be asked. – Woodsy Aug 10 '12 at 19:05
  • @Woodsy: It will be a cool application, best of luck for it. But I don't get how ur "getResourceId()" method will pick a random image. I think its trying to fetch images but its getting something else from res/drawable. Not sure, just an idea. – Harpreet Aug 10 '12 at 19:10
  • @Haps The app works fine for most users. I left some code out but the mArrayList is populated by a call to the database. Basically it does this: mObj = new mObj(filename); then add mObj to arraylist. from that I can call mObj.getResourceId(this); to get the corresponding resource id in the drawables folder. I haven't had this app crash on my devices but I keep getting error reports about it crashing for some users. – Woodsy Aug 10 '12 at 19:17
  • It really doesn't make any sense that four small bitmaps should cause memory problems, though. Anyway, glad that you fixed it. – Michell Bak Aug 10 '12 at 21:53
  • @MichellBak its not fixed. It works on my devices and most everyone else's but I keep getting the error from bugsense. I agree with you though 4 small images shouldn't cause out of memory crashes – Woodsy Aug 10 '12 at 23:09
  • @Woodsy Sorry, I just saw the answer that started with "What I did to solve this issue [...]", and didn't bother reading the name. We'll need a lot more code to help you with this one. – Michell Bak Aug 11 '12 at 09:11

1 Answers1

0

What I did to solve this issue is to remember only the resource id's of the images. I wrote an memory game with multiple card sets and tons of images. Use the resource id only when you paint. For this purpose I recomment to use a surface view and use the onDraw() to display the image.

Example in the onDraw():

mBoard[x][y] contains a resource id and is the gameboard.

bmp = BitmapFactory.decodeResource(mRes, mBoard[x][y]);

canvas.drawBitmap(bmp,null,rf,mPaint);

This will solve the memory issues even when you use hundreds of images.

Hope this helps Jasper

EdChum
  • 376,765
  • 198
  • 813
  • 562
jdekeij
  • 200
  • 1
  • 11
  • I've never tried to use a SurfaceView. I will try to do some examples and then see if your suggestion works. Thanks for the Suggestion. – Woodsy Aug 10 '12 at 20:29