代码之家  ›  专栏  ›  技术社区  ›  Mehmed Andrew Lam

如何在AsyncTask的doInBackground()中获取WeakReference

  •  0
  • Mehmed Andrew Lam  · 技术社区  · 6 年前

    我有一个班级叫 RetrieveCoverImageTask . 它从中的URL检索实际封面图像 Track 实例:

    private class RetrieveCoverImageTask extends AsyncTask<Track, Void, Void> {
    
        private WeakReference<Context> context;
    
        RetrieveCoverImageTask(Context context) {
            this.context = new WeakReference<>(context);
        }
    
        // V1
        @Override
        protected Void doInBackground(Track... tracks) {
            Context context = this.context.get();
            if (context != null) {
                for (Track track : tracks) {
                    try {
                        Bitmap bmp = Picasso.with(context).load(track.getCoverUrl()).get();
                        if (bmp != null) {
                            ByteArrayOutputStream stream = new ByteArrayOutputStream();
                            bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
                            track.setCoverImage(stream.toByteArray());
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            return null;
        }
    
        // V2
        @Override
        protected Void doInBackground(Track... tracks) {
            for (Track track : tracks) {
                try {
                    Context context = this.context.get();
                    if (context != null) {
                        Bitmap bmp = Picasso.with(context).load(track.getCoverUrl()).get();
                        if (bmp != null) {
                            ByteArrayOutputStream stream = new ByteArrayOutputStream();
                            bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
                            track.setCoverImage(stream.toByteArray());
                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return null;
        }
    }
    

    来自 Activity 具体如下:

    new RetrieveCoverImageTask(context).execute(track1, track2, track3);
    

    首先,我做了V1。然后,我认为毕加索的图像检索需要时间和调用 活动 同时可能会变为null,因此,我必须在for循环的每次迭代开始时获取上下文。这就是我实现V2的方式。

    哪个版本的 doInBackground() 是否高效且防错?V1或V2?

    3 回复  |  直到 6 年前
        1
  •  0
  •   Hendrik Marx    6 年前

    效率可能不是这里最大的问题。V2更安全,但整体不是很“优雅”。使用RxJava进行设置要容易得多。您不需要WeakReferences。关键是在上下文无效时(例如。 onDestroy() )然后将检查保存为null。

    此外,您可能希望使用一种不涉及毕加索的方法来获取bmp,因此不需要上下文。或者使用只要应用程序运行就存在的应用程序上下文,因此不需要空检查

        2
  •  0
  •   Marcos Vasconcelos    6 年前

    WeakReference。get是正确的。

    如果你想使用毕加索,你可以直接在视图上完成(可能是在BindViewHolder上),因为它已经在后台完成了。

    如果要使用任务,则需要使用URLConnection或OkHttp(最新版本,将其嵌入为URLConnection)来高效下载流

        3
  •  0
  •   karandeep singh    6 年前

    在异步任务中使用毕加索毫无意义,因为毕加索无论如何都会在不同的线程上异步加载图像。此外,您将位图存储在变量中,这将占用大量内存,因为位图很重,即使不需要,所有位图都将存储在ram中。一个更好的方法是,正如马科斯·瓦康塞洛斯所指出的那样,在你的取景器中直接使用毕加索。