我有多个对 AsyncTask 的调用,我想将其转换为 RxJava。AsyncTask 代码有效,但我只想探索如何在 RxJava 中做到这一点?
(顺便说一句,我知道标题很烂)
它能做什么:
- 循环通过 MyImageButton(它只是一个 POJO,不扩展 ImageButton)列表
- 在每个 MyImageButton 上,获取其当前位图(通过 getDrawable())
- 从 URL 获取图标。
- 合并两张图片 BitmapUtils.combine(...);
- 将此新组合的位图分配给 ImageButton
如何将其转换为 RxJava:
for (MyImageButton myImageButton: myImageButtons) {
final ImageButton imageButton = (ImageButton) findViewById(myImageButton.getImageButtonResId()); //getImageButtonResId holds a reference to some ImageButton
final Bitmap bitmap = ((BitmapDrawable) imageButton.getDrawable()).getBitmap();
new BindImageTask(imageButton, bitmap, myImageButton.getIconUrl()).execute();
}
这是 BindImageTask:
private class BindImageTask extends AsyncTask<Void, Void, Bitmap> {
private WeakReference<Bitmap> srcBitmapWeakReference;
private WeakReference<ImageButton> imageButtonWeakReference;
private String dstIconUrl;
BindImageTask(ImageButton imageButton, Bitmap srcBitmap, String dstIconUrl) {
srcBitmapWeakReference = new WeakReference<>(srcBitmap);
imageButtonWeakReference = new WeakReference<>(imageButton);
this.dstIconUrl = dstIconUrl;
}
@Override
protected Bitmap doInBackground(Void... params) {
Bitmap srcBitmap = srcBitmapWeakReference.get();
if (srcBitmap == null) return null;
Bitmap dstBitmap = ImageLoader.getInstance().loadImageSync(dstIconUrl, new ImageSize(60, 60));
if (dstBitmap == null) {
return null;
}
return BitmapUtils.combineImage(srcBitmap, dstBitmap, PorterDuff.Mode.DST_OVER);
}
@Override
protected void onPostExecute(Bitmap resultBitmap) {
super.onPostExecute(resultBitmap);
ImageButton imageButton = imageButtonWeakReference.get();
if (imageButton != null && resultBitmap != null) {
imageButton.setImageBitmap(resultBitmap);
}
}
}
现在我尝试在此上使用 RxJava,并且我对 RxJava 产生了这种不好的使用(它有效,但我知道有更好的方法):
Observable<MyImageButton> myImageButtonObservable = Observable.from(myImageButtons);
myImageButtonObservable
.map(new Func1<MyImageButton, MyImageButton>() {
@Override
public MyImageButton call(MyImageButton myImageButton) {
final ImageButton imageButton = (ImageButton) findViewById(myImageButton.getDialButtonResId());
final Bitmap srcBitmap = ((BitmapDrawable) imageButton.getDrawable()).getBitmap();
final Bitmap dstBitmap = ImageLoader.getInstance().loadImageSync(myImageButton.getIcon(), new ImageSize(60, 60));
final Bitmap newBitmap = BitmapUtils.combineImage(srcBitmap, dstBitmap, PorterDuff.Mode.DST_OVER);
ImageLoader.getInstance().getMemoryCache().put(myImageButton.getIconUrl() + "_compound", newBitmap);
return myImageButton;
}
})
.onErrorReturn(new Func1<Throwable, MyImageButton>() {
@Override
public MyImageButton call(Throwable throwable) {
return null;
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<MyImageButton>() {
@Override
public void call(MyImageButton myImageButton) {
if(myImageButton == null) {
return;
}
final ImageButton imageButton = (ImageButton) findViewById(myImageButton.getDialButtonResId());
imageButton.setImageBitmap(ImageLoader.getInstance().getMemoryCache().get(myImageButton.getIconUrl() + "_compound"));
}
});
我想要发生的是:
- 不必将新组合的图像保存到 ImageLoader 的缓存中。
- 在订阅回调中,我想引用这个新位图和对 MyImageButton 的引用,这样我就可以做一个简单的 myImageButton.setImageBitmap(newBitmap)。
我不想要的:
- 在 MyImageButton 类中有一个位图引用(因为我必须稍后对其进行序列化)。