Android AsyncTask 中的弱引用与强引用

WeakReference vs Strong Reference in Android AsyncTask

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

java 文档建议

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.

这是我的代码(为了简单起见,我只是分享我的 ListView 和 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;
    }

}

这是否有助于清理为 ImageView 加载的缩略图位图?

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

是的。弱引用将允许 GC 清除 m_imageView 以及从中可以访问的所有对象,以防 m_imageView 在某些时候仍然是弱可访问的。这可能会发生(例如)如果 Activity 保存 m_imageView 在您的 AsyncTask 加载新位图时被销毁。

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

以下是您在 Java 中获得的一些参考资料,按弱点升序排列

  1. 强引用 - 常规对象引用
  2. 弱引用 - 在下一个 GC 生命周期进行 GC
  3. 软参考
  4. 幻影引用

所以,是的。 Android 在您说完后不清理,使用导航离开。 AsyncTask 保留 运行 并在其内部 "lives" ImageView 引用。我对 WeakReference<T>s 的理解是,当用户导航离开时,它们确保 AsyncTask<T> 不会保留 ImageView 引用。进一步阅读 go etc here