【问题标题】:WeakReference vs Strong Reference in Android AsyncTaskAndroid AsyncTask 中的弱引用与强引用
【发布时间】:2016-08-14 13:53:22
【问题描述】:

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

java 文档建议

假设垃圾收集器在某个时间点确定一个对象是弱可达的。届时,它将自动清除对该对象的所有弱引用以及对通过强引用和软引用链可以访问该对象的任何其他弱可达对象的所有弱引用。

这是我的代码(为了简单起见,我只是分享了我的 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 加载的缩略图位图吗?

【问题讨论】:

    标签: java android android-asynctask weak-references


    【解决方案1】:

    这是否有助于清理正在加载的缩略图位图 图像视图?

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

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

    【讨论】:

    • 你也有来自 volley 的 NetworkImageView。很容易使用
    • @Laser,这个 NetworkImageView 对我来说是新的。谢谢!
    【解决方案2】:

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

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

    所以,是的。当您说,使用导航离开时,Android 不会在您之后清理。 AsyncTask 继续运行,并在其内部“生活”ImageView 引用。我对WeakReference&lt;T&gt;s 的理解是,他们确保AsyncTask&lt;T&gt; 在用户离开时不会保留ImageView 引用。进一步阅读 go etc here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多