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?
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.