WeakReference与Android AsyncTask中的强引用

时间:2016-08-14 13:53:23

标签: java android android-asynctask weak-references

我正在实现一个列表视图,以显示DCIM / Camera文件夹下的图像列表。我正在异步加载列表视图上的图像缩略图,并在我的AsyncTask实现中使用ImageView的强引用,即 ThumbnailReaderTask ,此AsyncTask负责加载图像缩略图。我被建议使用ImageView的WeakReference。我很好奇在这种特殊情况下使用WeakReference会有什么好处。

java文档建议

  

假设垃圾收集器在某个时间点确定对象是弱可达的。那时它将原子地清除对该对象的所有弱引用以及对任何其他弱可达对象的所有弱引用,通过一系列强引用和软引用可以从该对象到达该对象。

这是我的代码(为了简单起见,我只是为ListView和ThumbnailReaderTask共享我的Adapter实现)。

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;
    }

}

这有助于清除为ImageView加载的缩略图位图吗?

2 个答案:

答案 0 :(得分:2)

  

这有助于清理正在加载的缩略图位图   ImageView的?

是。弱引用将允许GC清除m_imageView,并且如果m_imageView在某些时候仍然无法访问,则可以从中访问所有对象。如果在Activity加载新位图时m_imageView AsyncTask被解除,则会发生这种情况(例如)。

但是,我建议你不要走这条路,而是使用一个可用的库来同步加载图像。原因很简单:这是一项非常重要且耗时的任务,您需要在此过程中解决大量漏洞。查看UniversalImageLoader或Picasso。

答案 1 :(得分:1)

以下是您在Java中按弱点递增顺序获得的一些参考资料

  1. 强引用 - 常规对象引用
  2. 弱参考 - 在下一个GC生命周期进行GC编辑
  3. 软参考
  4. 幻影参考
  5. 那么,是的。在您说完使用导航后,Android无法清理。 AsyncTask一直在运行,并在其自身内生活&#34; ImageView引用。我对WeakReference<T>的理解是,他们确保AsyncTask<T>在用户导航时不会保留ImageView引用。进一步阅读等here