3

I have the following method which has an ImageSwitcher that the user can slide left and right. The selected image is displayed in the center of the screen. I've done some image scaling for high res images on low memory phones, but I still run into Bitmap OutOfMemoryEexception when sliding quickly left to right. I'd like to transform the line mSwitcher.setImageURI(myUri);(This is the line that is causing the OOME) to use a weak reference, so that it can be automatically garbage collected. How can I do this? Is this the best way to performance optimize this method?

Thanks

method:

    public void onItemSelected(AdapterView parent, View v, int position, long id) {

    File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_PICTURES), "MyAppName");
    File[] cachedOnSDImages = mediaStorageDir.listFiles();
    countArray = new Integer[cachedOnSDImages.length];
    fileArray = new String[cachedOnSDImages.length];
    fileArray[position] = cachedOnSDImages[position].getAbsolutePath();
    Uri myUri = Uri.parse(fileArray[position]);
    mSwitcher.setImageURI(myUri); // weakly reference myUri in this line
    this.currentpos = position;
}

I should add the mSwitcher is instantiated here:

    private void makeSwitcher() {
    mSwitcher =  (ImageSwitcher) findViewById(R.id.switcher);
    mSwitcher.setFactory(this);
    mSwitcher.setInAnimation(AnimationUtils.loadAnimation(this,
        android.R.anim.fade_in));
    mSwitcher.setOutAnimation(AnimationUtils.loadAnimation(this,
        android.R.anim.fade_out));
}
KDEx
  • 3,505
  • 4
  • 31
  • 39

1 Answers1

5
import java.lang.ref.WeakReference;

public class ReferenceTest {
        public static void main(String[] args) throws InterruptedException {

            WeakReference r = new WeakReference(new String("I'm here"));
            WeakReference sr = new WeakReference("I'm here");
            System.out.println("before gc: r=" + r.get() + ", static=" + sr.get());
            System.gc();
            Thread.sleep(100);

            // only r.get() becomes null
            System.out.println("after gc: r=" + r.get() + ", static=" + sr.get());

        }
}

Taken from wiki Weak references

This is how Weak references can be used in Java - however this also means that it will not work in your case since switcher would have to explicitly accept a WeakReference Object instead of a URI.

dngfng
  • 1,923
  • 17
  • 34
  • I've read over that example. I'd added to my code where mSwitcher is instantiated. Is it possible to weakly reference or create a new instance of myUrl each time its called? – KDEx Oct 16 '12 at 13:47
  • I week references are going to help you in this case. Essentially it is also a bad idea - since the object can be killed by the GC at any time. The most sensible thing todo is to dereference the uri when it isn't needed any more - either by replacing it with the a new uri or setting the variable to null. At this point the URI Object will be eligible for garbarge collection. – dngfng Oct 16 '12 at 14:29