我有一个名为RetrieveCoverImageTask
的班级。它从Track
实例中的URL检索实际封面图像:
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。然后,我认为使用Picasso进行图像检索需要时间,同时调用Activity
可能会变为空,因此,我必须在for循环的每次迭代开始时获取上下文。这就是我实施V2的方式。
哪个版本的doInBackground()
有效且无错误? V1或V2?
答案 0 :(得分:0)
效率可能不是这里最大的问题。 V2更安全,但整件事情并不是很优雅&#34;。使用RxJava设置内容要容易得多。你不需要WeakReferences。关键是在上下文无效时处理您的订阅(例如onDestroy()
)并且您将检查保存为空。
此外,您可能希望使用一种方法来获取不涉及毕加索的bmp,因此不需要上下文。或者,只要应用程序正在运行,您就会使用存在的应用程序上下文,因此您不需要空检查
答案 1 :(得分:0)
WeakReference.get是正确的。
如果你想使用Picasso,可以直接在View(可能是onBindViewholder)上进行,因为它已经在后台执行了。
如果你想使用一个任务,你需要下载流而不是URLConnection才能有效,或者OkHttp(最新版本,导致它嵌入为URLConnection)
答案 2 :(得分:0)
在异步任务中使用Picasso毫无意义,因为Picasso无论如何都会在不同的线程上异步加载图像。此外,您将位图存储在变量中会占用大量内存,因为位图很重,所有这些都将存储在ram中,即使它们不是必需的。更好的方法是在Marcos Vasconcelos指出的ViewHolder中直接使用Picasso。