g0ldsteinsbr0
g0ldsteinsbr0

Reputation: 249

bitmap size exceeds VM budget on old devices

I'm getting an Exception in the BitmapFactory. I've read on the other questions that the only solution is to load a scaledown version of my images, but in my case, I need to display them in full resolution with a pinch to zoom system (the images are flyers that include text). The images are only 466x700px for 300ko, they are displayed like this :

Viewpager class :

@Override
public View instantiateItem(ViewGroup container, int position) {
    ImageView imageView = new ImageView(container.getContext());
    PhotoViewAttacher attacher = new PhotoViewAttacher(imageView);
    try {
        Drawable toRecycle = imageView.getDrawable();
        if (toRecycle != null) {
            ((BitmapDrawable) imageView.getDrawable()).getBitmap().recycle();
        }
        imageView.setImageDrawable(getCat()[position]);
    } catch (IOException e) {
        e.printStackTrace();
    }
    attacher.update();
    container.addView(imageView);
    return imageView;
}

And the getCat() :

public static Drawable[] getTheme_amiante_s_carreleur(Context ctx) throws IOException {
    ZipResourceFile expansionFile = APKExpansionSupport.getAPKExpansionZipFile(ctx, 2, 1);
    Drawable[] theme_amiante_s_carreleur = {
        Drawable.createFromStream(expansionFile.getInputStream("amiante_carreleur_s_1.png"), "src"),
        Drawable.createFromStream(expansionFile.getInputStream("amiante_carreleur_s_2.png"), "src"),
        Drawable.createFromStream(expansionFile.getInputStream("amiante_carreleur_s_3.png"), "src"),
        Drawable.createFromStream(expansionFile.getInputStream("amiante_carreleur_s_4.png"), "src"),
        Drawable.createFromStream(expansionFile.getInputStream("amiante_carreleur_s_5.png"), "src"), };
    return theme_amiante_s_carreleur;
}

It works fine on my Nexus 4, but on a Galaxy S2 or a LG Optimus Black, the system quickly force close due to a Out Of Memory error :

java.lang.OutOfMemoryError: bitmap size exceeds VM budget 
at android.graphics.BitmapFactory.nativeDecodeStream(Native Method) 
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:573) 
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:439) 
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:697) 
at android.graphics.drawable.Drawable.createFromStream(Drawable.java:657) 
at com.ctai.iris.ListeImages.getTheme_formation_ce_obligatoires(ListeImages.java:1163) 
at com.ctai.iris.ImageViewLow.getCat(ImageViewLow.java:186) 
at com.ctai.iris.ImageViewLow$SamplePagerAdapter.instantiateItem(ImageViewLow.java:77) 
at com.ctai.iris.ImageViewLow$SamplePagerAdapter.instantiateItem(ImageViewLow.java:1) 
at android.support.v4.view.ViewPager.addNewItem(ViewPager.java:801) 
at android.support.v4.view.ViewPager.populate(ViewPager.java:992) 
at android.support.v4.view.ViewPager.populate(ViewPager.java:881) 
at android.support.v4.view.ViewPager$3.run(ViewPager.java:237) 
at android.os.Handler.handleCallback(Handler.java:587)
at android.os.Handler.dispatchMessage(Handler.java:92) 
at android.os.Looper.loop(Looper.java:130) 
at android.app.ActivityThread.main(ActivityThread.java:3691) 
at java.lang.reflect.Method.invokeNative(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:507) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:907) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:665) 
at dalvik.system.NativeStart.main(Native Method)

Any idea how I can handle this problem ?

Upvotes: 2

Views: 977

Answers (2)

DigCamara
DigCamara

Reputation: 5568

Like I said in my comments to @Raghunandan: when you recycle a Bitmap, the important part is actually having set all references to it to null. The documentation says

This is an advanced call, and normally need not be called, since the normal GC process will free up this memory when there are no more references to this bitmap.

Also, in your case, I'd recommend to use the techniques described in the section "Caching Bitmaps" of the Android Developer site. It's part of the "Displaying Bitmaps Efficiently" lessons.

Upvotes: 0

Raghunandan
Raghunandan

Reputation: 133560

Recycle bitmaps when not in use. Compress the bitmap to reduce memory usage. Have a look ath this link. http://developer.android.com/training/displaying-bitmaps/load-bitmap.html.

Use a MAT Analyzer to check how much memory is used by bitmap.

Check the link. Talks about memory management and how to use MAT to find memory leaks. http://www.youtube.com/watch?v=_CruQY55HOk.

Also remove the static for Drawables. I am not sure, but give it a try.

Upvotes: 2

Related Questions