17

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?

MysticMagicϡ
  • 28,593
  • 16
  • 73
  • 124
Prexx
  • 2,959
  • 5
  • 31
  • 48
  • 1
    try calling .recycle() on your bitmaps in OnPause(). and load them in onResume() not onCreate(). – pumpkee Jan 16 '13 at 13:03
  • is it possible to do this in a better way? like, if all my bitmaps are located in a linearlayout, then calling llMain.recycle(), or something like that? – Prexx Jan 16 '13 at 13:07
  • You could create an ArrayList to which you add every bitmap that you load and recycle looping through that. Another general thing: Play with the sample size of the image. Don't know what your app is for but for simply showing the bitmap on the screen most of the time it's still sufficiant to sample them down and save memory. See : http://developer.android.com/training/displaying-bitmaps/load-bitmap.html – pumpkee Jan 16 '13 at 13:12
  • I also faced this problem and I use [How to resolve outofmemory Error ?](http://stackoverflow.com/questions/477572/android-strange-out-of-memory-issue-while-loading-an-image-to-a-bitmap-object/823966#823966). I think it will helps you. – Hardik Joshi Jan 16 '13 at 13:14
  • Is there any chance to get the bitmap out of an imagebutton? – Prexx Jan 16 '13 at 15:20
  • Yes. Bitmap bitmap = ((BitmapDrawable)imageButton.getDrawable()).getBitmap(); – pumpkee Jan 18 '13 at 11:08

4 Answers4

32

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

Padma Kumar
  • 19,893
  • 17
  • 73
  • 130
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

smoothumut
  • 3,423
  • 1
  • 25
  • 35
0

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. :-)

Broo
  • 859
  • 4
  • 11
  • 21
  • i tried to finish activitys, but as a result, i went back an activity.. example: im on A3 and wanna go to A1: i call startIntent(A1) and finish --> im on A2.. :/ – Prexx Jan 16 '13 at 13:10
  • Ok, so I think if you override onStop() for each activity and put finish() within that method that should finish that activity and release the resources rather than the system holding it in memory once the next activity has started. Make sure the finish() isnt terminating the current activity. – Broo Jan 16 '13 at 13:24
0

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);
Yogesh Tatwal
  • 2,722
  • 20
  • 43