2

I am getting OutOfMemoryError on my application. When i went through some tutorials, i came to know that, I can solve this issue by using Softreference/Weakreference. But I don't know that how to use Softreference/Weakreference.

Please suggest me some tutorials that providing examples for the Softreference or Weakreference.

Thank you...

2 Answers 2

3
package com.myapp;

import java.io.File;
import java.lang.ref.SoftReference;
import java.util.WeakHashMap;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;


public class BitmapSoftRefrences {


      public static String SDPATH = Environment.getExternalStorageDirectory()
        + "/MYAPP";

// 1. create a cache map
public static WeakHashMap<String, SoftReference<Bitmap>> mCache = new WeakHashMap<String, SoftReference<Bitmap>>();
public static String TAG = "BitmapSoftRefrences";

// 2. ask for bitmap
public static Bitmap get(String key) {
    if (key == null) {
        return null;
    }

    try {
        if (mCache.containsKey(key)) {

            SoftReference<Bitmap> reference = mCache.get(key);
            Bitmap bitmap = reference.get();
            if (bitmap != null) {
                return bitmap;
            }
            return decodeFile(key);
        }

    } catch (Exception e) {
        // TODO: handle exception
        Logger.debug(BitmapSoftRefrences.class,
                "EXCEPTION: " + e.getMessage());

    }

    // the key does not exists so it could be that the
    // file is not downloaded or decoded yet...

    File file = new File(SDPATH + "/" + key);

    if (file.exists()) {
        return decodeFile(key);
    } else {
        Logger.debug(BitmapSoftRefrences.class, "RuntimeException");

        throw new RuntimeException("RuntimeException!");
    }
}

// 3. the decode file will return bitmap if bitmap is not cached
public static Bitmap decodeFile(String key) {
    // --- prevent scaling
    BitmapFactory.Options opt = new BitmapFactory.Options();
    opt.inScaled = false;

    Bitmap bitmap = BitmapFactory.decodeFile(SDPATH + "/" + key, opt);

    mCache.put(key, new SoftReference<Bitmap>(bitmap));

    return bitmap;
}

public static void clear() {
    mCache.clear();
}

}
Sign up to request clarification or add additional context in comments.

Comments

0

To create a WeakReference, the syntax is WeakReference<SomeType> myWeakReference = new WeakReference<SomeType>(actualObject);. To retrieve the object via that WeakReference, do the check if (weakWidget == null). That way, you will avoid a NullPointerException if it has been garbage-collected already.

This Java.net article by Ethan Nicholas explains why you would want to use a WeakReference instead of a strong one. It provides the example of a final (unextendible) class called Widget that has no defined serial UID, presuming that the developer decides to define a serial UID to track each Widget instance. They do so by creating a new HashMap and doing something like serialNumberMap.put(widget, widgetSerialNumber); which is a strong reference. That means it must be explicitly cleaned up when no longer needed. The developer is responsible for knowing exactly when to manually "garbage-collect" that reference and remove it from the HashMap, which should be done only when they're really sure it's not needed anymore. This may be the problem you ran into in your application.

In this particular case, as the article explains, the developer could use the WeakHashMap class instead (as @NayAneshGupte put in his example), wherein the key is actually a WeakReference. This would allow the JVM nullify the keys to old Widgets as it saw fit, so that the garbage collector could come along and destroy their associated objects.

The article also goes on to talk about SoftReferences and PhantomReferences (which I've never used). You can read more about all of these in this javapapers.com article and this Rally blog.

3 Comments

@CodyGray--ironically, the original accepted answer was also a link. While you definitely have a point (and I had not realized it when answering this originally), even the thread you referenced reveals varying opinions about whether a link can be a good answer in and of itself. To that end, would it have been acceptable for me to have posted this as a comment on another answer (instead of as an answer)?
I left the same comment on the original post—link-only answers are not acceptable answers, whether someone else does it first or not. The better solution would have been to include the essential parts of the answer here, and just provide the link for reference. Yes, you could have left a comment, but that's not the same thing as an answer.
Anybody like my answer better, now that I've revised it? :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.