Passion
Passion

Reputation: 662

Out of Memory on Bitmap Android

I want to make implement this in android enter image description here For this, I have to load images from asset folder and I am making two HorizontalScrollView in xml file and load dynamically ImageView in it. For loading ImageView I am using this code

LinearLayout myGallery = (LinearLayout) findViewById(R.id.mygallery);

try {
    String galleryDirectoryName = "gallery";
    String[] listImages = getAssets().list(galleryDirectoryName);
    for (String imageName : listImages) {
        InputStream is = getAssets().open(galleryDirectoryName + "/" + imageName);
        Bitmap bitmap = BitmapFactory.decodeStream(is);

        ImageView imageView = new ImageView(getApplicationContext());
        imageView.setLayoutParams(new ViewGroup.LayoutParams(100, 100));

        //   imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
        imageView.setImageBitmap(bitmap);

        LinearLayout.LayoutParams myGallery1=  new LinearLayout.LayoutParams(100, 100);
        myGallery1.setMargins(20, 0,  10, 0);

        //its is also working
        // imageView.setLayoutParams(myGallery1);       

        imageView.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                //   diplayImage.setImageBitmap(bitmap);
            }
        });

        Log.e("GalleryWithHorizontalScrollView", e.getMessage(), e);
    }

//Repeating Above code to load imageView in second horizontalScrollView

LinearLayout myGallery2 = (LinearLayout) findViewById(R.id.mygallery2);

try {
    String galleryDirectoryName1 = "gallery2";
    String[] listImages2 = getAssets().list(galleryDirectoryName1);
    for (String imageName : listImages2) {
        InputStream is1 = getAssets().open(galleryDirectoryName1 + "/" + imageName);
        Bitmap bitmap1 = BitmapFactory.decodeStream(is1);

        ImageView imageView = new ImageView(getApplicationContext());
        imageView.setLayoutParams(new ViewGroup.LayoutParams(100, 100));

        //  imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
        imageView.setImageBitmap(bitmap1);

        LinearLayout.LayoutParams myGallery21=  new LinearLayout.LayoutParams(100, 100);
        myGallery21.setMargins(20, 40,  10, 0);

        //its is also working

        myGallery.addView(imageView,myGallery1);
    }
} catch (IOException e) {
    myGallery2.addView(imageView,myGallery21);
        }
} catch (IOException e) {
    Log.e("GalleryWithHorizontalScrollView", e.getMessage(), e);
}
}

If I make one horizontalScrollView and load imageviews in it then it works fine but for second horizontalScrollView it gives me error at line 76

Bitmap bitmap1 = BitmapFactory.decodeStream(is1);

and my Log cat is this

05-14 11:13:26.000: E/AndroidRuntime(8350): FATAL EXCEPTION: main
05-14 11:13:26.000: E/AndroidRuntime(8350): java.lang.OutOfMemoryError
05-14 11:13:26.000: E/AndroidRuntime(8350):     at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
05-14 11:13:26.000: E/AndroidRuntime(8350):     at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:577)
05-14 11:13:26.000: E/AndroidRuntime(8350):     at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:643)
05-14 11:13:26.000: E/AndroidRuntime(8350):     at com.example.gallery.MainActivity.onCreate(MainActivity.java:76)
05-14 11:13:26.000: E/AndroidRuntime(8350):     at android.app.Activity.performCreate(Activity.java:4470)
05-14 11:13:26.000: E/AndroidRuntime(8350):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1053)
05-14 11:13:26.000: E/AndroidRuntime(8350):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1934)
05-14 11:13:26.000: E/AndroidRuntime(8350):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1995)
05-14 11:13:26.000: E/AndroidRuntime(8350):     at android.app.ActivityThread.access$600(ActivityThread.java:128)
05-14 11:13:26.000: E/AndroidRuntime(8350):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1161)
05-14 11:13:26.000: E/AndroidRuntime(8350):     at android.os.Handler.dispatchMessage(Handler.java:99)
05-14 11:13:26.000: E/AndroidRuntime(8350):     at android.os.Looper.loop(Looper.java:137)
05-14 11:13:26.000: E/AndroidRuntime(8350):     at android.app.ActivityThread.main(ActivityThread.java:4517)
05-14 11:13:26.000: E/AndroidRuntime(8350):     at java.lang.reflect.Method.invokeNative(Native Method)
05-14 11:13:26.000: E/AndroidRuntime(8350):     at java.lang.reflect.Method.invoke(Method.java:511)
05-14 11:13:26.000: E/AndroidRuntime(8350):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:993)
05-14 11:13:26.000: E/AndroidRuntime(8350):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:760)
05-14 11:13:26.000: E/AndroidRuntime(8350):     at dalvik.system.NativeStart.main(Native Method)

Upvotes: 0

Views: 648

Answers (3)

Chirag Jain
Chirag Jain

Reputation: 1612

You can find your answer here,

and most important thing you should consider is to optimize your bitmap for your thumbnail. Try this :

public static Bitmap decodeSampledBitmapFromInput(Context context,
        InputStream input, int reqWidth, int reqHeight) {

    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeStream(input, null, options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth,
            reqHeight);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeStream(input, null, options);
}

Here reqWidth is width of thumbnail and same for reqHeight.

and For listView try to implement a cache for your bitmaps and try to get them by using a unique key may be file name (because you should not save same images multiple times)

Upvotes: 1

Arun C
Arun C

Reputation: 9035

You need to access images using BitmapFactory.Options

 BitmapFactory.Options options = new BitmapFactory.Options();
    options.inSampleSize =8;

then

Bitmap bitmap1 = BitmapFactory.decodeStream(is1,null,options);

So that only required size bitmap is loaded into memory

For more see Loading Large Bitmaps Efficiently

Upvotes: 0

Kitesurfer
Kitesurfer

Reputation: 3561

Simple, dont load to much Images ...

Use some caching like an LRUCache with an fixed size. If Image is missing you have to load them first. Should increase performance and fix your OOME

http://developer.android.com/reference/android/util/LruCache.html

Upvotes: 0

Related Questions