Search code examples
androideclipseandroid-4.0-ice-cream-sandwich

How to use an ImageView without de/allocating memory


I have an application that uses a flip-book style animation with thousands of images. APK size isn't an issue due to it being an internal only application that will never be put on any app store.

The issue I am having is my animator is a sub-classed ImageView that switches out images at 15 frames per second and each time I call setImageURI Garbage Collection then runs. So is there an alternative method to setImageURI that wont cause Garbage Collection to be run?

Edit: A little more background information.

My app has ~12 sequences and 6 of them contain 1609 Images and different events need to be called at certain frames. Another need is for the user to be able to stop on any frame to survey the situation and either preform an action or continue down the sequence. A 3D engine would have been the ideal solution but this method was brought up as the user doesn't need complete freedom and is on a "rail" the entire time.

This is the meat of the application and where the problem occurs

try {
   ((BitmapDrawable) getDrawable()).getBitmap().recycle();
   setImageURI(imgUri);
   refreshDrawableState();
} catch (Exception e) {
   e.printStackTrace();
}

Solution

  • The Garbage Collector is running because you're exchanging one image for another which dumps the previous. It's going to happen every time you lose references to the images.

    Here are a couple possible methods to consider.

    1. Since you mentioned it's a flipbook, build and assign an AnimationDrawable to the ImageView which will act as a frame-by-frame animation (exactly what a flipbook is). This loads all the images at once and will keep them around until you lose a reference to the AnimationDrawable.

    2. Store all the images as SoftReferences to cache the images. A SoftReference will keep the object in memory until memory is needed to be collected. This will slow the frequency of the garbage collector (assuming this is the cause). Use BitmapFractory to build the image and setImageBitmap to assign it to the ImageView. The other advantage of this is it allows you to build images on threads before you assign it to the ImageView.