Out of Memory Error while loading bitmaps

2019-01-06 23:20发布

问题:

i have an android app with 3 acitivtys:

A1 --starts--> A2 --starts--> A3 --when finished his process: starts--> A1

(so i don't "finish();" an app. i start the next activitys with "startActivity(..);" the whole time after userinteraction)

so there is a loop in these 3 activitys. On each Activity, i display 3-9 pictures, located on the SD-card, which i load with my following function:

try
{
    Uri selectedImageURI = Uri.parse(strImagePath);
    File imgFile = new  File(getRealPathFromURI(selectedImageURI, c));
    Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
    ivTmp.setImageBitmap(myBitmap);
}catch (Exception e)
{
    return null;
}

This all works. But sometimes (after looping a few times through my activitys), my app crashes..

Logcat tells me:

01-16 13:42:15.863: DEBUG/dalvikvm(23161): GC_BEFORE_OOM freed 10K, 9% free 59019K/64400K, paused 29ms, total 30ms
01-16 13:42:15.863: ERROR/dalvikvm-heap(23161): Out of memory on a 8018704-byte allocation.
01-16 13:42:15.863: ERROR/AndroidRuntime(23161): FATAL EXCEPTION: main
        java.lang.OutOfMemoryError
        at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
        at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:502)
        at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:355)
        at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:785)
        at android.content.res.Resources.loadDrawable(Resources.java:1965)
        at android.content.res.Resources.getDrawable(Resources.java:660)
        at android.widget.ImageView.resolveUri(ImageView.java:616)
        at android.widget.ImageView.setImageResource(ImageView.java:349)
        at <MyApp>.MyActivity$6.run(MyActivity.java:143)
        at android.os.Handler.handleCallback(Handler.java:725)
        at android.os.Handler.dispatchMessage(Handler.java:92)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:5039)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
        at dalvik.system.NativeStart.main(Native Method)

Someone can give my some tips how to handle the crashes? Maybe its because my activitys are set to state "paused" instead of closing them correctly?

回答1:

for quick fix you can add

android:largeHeap="true" in your manifest application tag

link here:

I face OOM problem for my table in kindle and nook

Heap size (large)
android:largeHeap="true"

there specification is mentioned to use larger heap link here:

edit: use Caching Bitmaps technique link here



回答2:

I had the similar problem while displaying high resolution images. I have searched and applied all the android bitmap solutions given in http://developer.android.com/training/displaying-bitmaps/index.html and the following caches mekanism in the link. but none of them work. not any right solution anywhere. Then I figured out that the problem is : I couldnt use the drawable folder structure right. I was keeping high resolution images in mdpi and hdpi folders . this cause android scale up the images to the ultra sizes. 100 kb image was causing 20 mb increase in memory thanks to the android monitor / memory section. so I have added these ultra resolution images to xxhdpi folder , then It was FIXED suddenly. then my image slider work flawlessly



回答3:

Yeah android doesnt immediately destroy activities when they are not visible to the user, but there are a number of lifecycle methods that are called depending on the current state. Check out http://developer.android.com/guide/components/activities.html#Lifecycle

You could try finishing the activities in onStop() or onDestroy() as these will be called when the activity is not visible and when the system runs low on memory respectively. :-)



回答4:

This is due to the high resolution of image you have to scaling the bitmap use the following code

 Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());

    int h = 100; // height in pixels
    int w = 100; // width in pixels
Bitmap photoBitMap = Bitmap.createScaledBitmap(myBitmap,h, w, true);
ivTmp.setImageBitmap(photoBitMap);