Out of Memory on Bitmap Android

断了今生、忘了曾经 提交于 2019-12-12 03:25:57

问题


I want to make implement this in android

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)

回答1:


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)




回答2:


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




回答3:


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



来源:https://stackoverflow.com/questions/16536329/out-of-memory-on-bitmap-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!