Search code examples
javaandroidandroid-asynctaskweak-references

WeakReference vs Strong Reference in Android AsyncTask


I am implementing a list view to show a list of images under DCIM/Camera folder. I am loading images thumbnails on list view asynchronously and using Strong reference of ImageView in my AsyncTask implementation i.e. ThumbnailReaderTask, this AsyncTask is responsible for loading the image thumbnails. I have been suggested to use the WeakReference of ImageView. I am just curious that what good I would achieve by using WeakReference in this particular scenario.

The java documentation suggests

Suppose that the garbage collector determines at a certain point in time that an object is weakly reachable. At that time it will atomically clear all weak references to that object and all weak references to any other weakly-reachable objects from which that object is reachable through a chain of strong and soft references.

Here is my code (To keep things simple, I am just sharing my Adapter implementation for ListView and ThumbnailReaderTask).

ImageListEntry

//The model class
public class ImageListEntry {

    String m_name;
    public String getName(){
        return m_name;
    }

    public void setName(String value){
        m_name = value;
    }

    File m_file;
    public File getFile(){
        return m_file;
    }
    public void setFile(File value){
        m_file = value;
    }

}

ImageListAdapter

public class ImageListAdapter extends BaseAdapter {

    Activity m_context;
    List<ImageListEntry> m_images;

    public ImageListAdapter(Activity context, List<ImageListEntry> images){

        this.m_context = context;
        this.m_images = images;
    }

    @Override
    public long getItemId(int position) {

        return position;
    }

    @Override
    public Object getItem(int position) {

        return m_images.get(position);
    }

    @Override
    public int getCount() {

        return m_images.size();
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        ImageListEntry currentImage = m_images.get(position);
        TextView nameTextView = (TextView)convertView.findViewById(R.id.explorer_resName);
        nameTextView.setText("Set some text...");
        ImageView thumbnailImageView = (ImageView)convertView.findViewById(R.id.explorer_resIcon);
        //Asynchronous image loading
        new ThumbnailReaderTask(thumbnailImageView).execute(currentImage.getFile());
        return convertView;
    }
}

ThumbnailReaderTask

public class ThumbnailReaderTask extends AsyncTask<File, Void, Bitmap> {

    //Should use WeakReference<ImageView>m_imageViewReference
    private final ImageView m_imageView;

    public ThumbnailReaderTask(ImageView imageView) {
        m_imageView = imageView;
    }

    @Override
    protected Bitmap doInBackground(File... params) {
        return readBitmapFromFile(params[0]);
    }

    @Override
    protected void onPostExecute(Bitmap bitmap) {

        ImageView imageView = m_imageView;//m_imageViewReference.get();
        if (imageView != null) {

            if (bitmap != null) {
                imageView.setImageBitmap(bitmap);
            }else {

                Drawable placeholder = imageView.getContext().getResources().getDrawable(R.mipmap.filetype_image);
                imageView.setImageDrawable(placeholder);
            }
        }

    }

    private Bitmap readBitmapFromFile(File file){

        //read thumbnail and return;
    }

}

Would that help in cleaning thumbnail bitmap being loaded for ImageView?


Solution

  • Would that help in cleaning thumbnail bitmap being loaded for ImageView?

    Yes. Weak reference will allow GC to clear m_imageView and all objects reachable from it in case m_imageView remains weakly reachable at some point. This could happen (for example) if Activity that holds m_imageView is destroyed while your AsyncTask is loading a new bitmap.

    However, I would advice you not to go down this road, but use one of the available libraries for async loading of images. The reason is simple: it is non-trivial and time-consuming task, and you'll need to resolve a ton of bugs along the way. Check out UniversalImageLoader or Picasso.