android - Convert AsyncTask With Multiple Parameters to RxJava -
i have multiple calls asynctask convert rxjava. asynctask code works, explore how in rxjava?
(by way, know title sucks)
what does:
- loop through myimagebutton (which pojo, not extending imagebutton) list
- on each myimagebutton, current bitmap (through getdrawable())
- get icon url.
- on combine 2 images bitmaputils.combine(...);
- assign newly combined bitmap imagebutton
how convert rxjava:
(myimagebutton myimagebutton: myimagebuttons) { final imagebutton imagebutton = (imagebutton) findviewbyid(myimagebutton.getimagebuttonresid()); //getimagebuttonresid holds reference imagebutton final bitmap bitmap = ((bitmapdrawable) imagebutton.getdrawable()).getbitmap(); new bindimagetask(imagebutton, bitmap, myimagebutton.geticonurl()).execute(); }
here's 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); } } }
now tried use rxjava on and, produced bad use of rxjava (it works, know there's better way):
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")); } });
what wanted happen is:
- not having save newly combined image imageloader's cache.
- on subscribe callback want have references both new bitmap , reference myimagebutton can simple myimagebutton.setimagebitmap(newbitmap).
what don't want:
- to have bitmap reference inside myimagebutton class (since have serialize later).
first way. using helper class data
create class data.java
:
public static class data{ private imagebutton imagebutton; private bitmap srcbitmap; private bitmap dstbitmap; private bitmap combinedbitmap; private string dsticonurl; public data(imagebutton imagebutton, string iconurl) { this.imagebutton = imagebutton; srcbitmap = ((bitmapdrawable) imagebutton.getdrawable()).getbitmap(); dsticonurl = iconurl; } public imagebutton getimagebutton() { return imagebutton; } public bitmap getsrcbitmap() { return srcbitmap; } public bitmap getdstbitmap(){ return dstbitmap; } public string getdsticonurl() { return dsticonurl; } public bitmap getcombinedbitmap(){ return combinedbitmap; } public data withimagebutton(imagebutton btn){ this.imagebutton = btn; return this; } public data withsrcbitmap(bitmap bitmap){ this.srcbitmap = bitmap; return this; } public data withiconurl(string url){ this.dsticonurl = url; return this; } public data withdstbitmap(bitmap bitmap){ this.dstbitmap = bitmap; return this; } public data withcombinedbitmap(bitmap bitmap){ this.combinedbitmap = bitmap; return this; } }
process buttons class data
:
observable.from(myimagebuttons) .map(new func1<myimagebutton, data>() { @override public data call(myimagebutton myimagebutton) { return new data(myimagebutton, myimagebutton.geticonurl()); } }) .map(new func1<data, data>() { @override public data call(data data) { return data.withdstbitmap(imageloader.getinstance().loadimagesync(data.getdsticonurl(), new imagesize(60, 60))); } }) .filter(new func1<data, boolean>() { @override public boolean call(data data) { return data.getdstbitmap() != null; } }) .map(new func1<data, data>() { @override public data call(data data) { return data.withcombinedbitmap(bitmaputils.combineimage(data.getsrcbitmap(), data.getdstbitmap(), porterduff.mode.dst_over)); } }) .subscribeon(schedulers.computation()) .observeon(androidschedulers.mainthread()) .subscribe( new action1<data>() { @override public void call(data data) { //onnext data.getimagebutton().setimagebitmap(data.getcombinedbitmap()); //i recomend recycle old bitmaps if no needed data.getsrcbitmap().recycle(); data.getdstbitmap().recycle(); data.withsrcbitmap(null).withdstbitmap(null); //complex way remove bitmaps cache //see http://stackoverflow.com/a/19512974/1796309 //memorycacheutils.removefromcache(data.getdstbitmap(), imageloader.getinstance().getmemorycache()); //disccacheutils.removefromcache(data.getdstbitmap(), imageloader.getinstance().getdisccache()); } }, new action1<throwable>() { @override public void call(throwable throwable) { //onerror throwable.printstacktrace(); } }, new action0() { @override public void call() { //simple way clear imageloadercache imageloader.getinstance().clearmemorycache(); } } );
or use lambda expressions:
observable.from(myimagebuttons) .map(myimagebutton -> new data(myimagebutton, myimagebutton.geticonurl())) .map(data -> data.withdstbitmap(imageloader.getinstance().loadimagesync(data.getdsticonurl(), new imagesize(60, 60)))) .filter(data -> data.getdstbitmap() != null) .map(data -> data.withcombinedbitmap(bitmaputils.combineimage(data.getsrcbitmap(), data.getdstbitmap(), porterduff.mode.dst_over))) .subscribeon(schedulers.computation()) .observeon(androidschedulers.mainthread()) .subscribe( data -> { //onnext data.getimagebutton().setimagebitmap(data.getcombinedbitmap()); //i recomend recycle old bitmaps if no needed data.getsrcbitmap().recycle(); data.getdstbitmap().recycle(); data.withsrcbitmap(null).withdstbitmap(null); //complex way remove bitmaps cache //see http://stackoverflow.com/a/19512974/1796309 //memorycacheutils.removefromcache(data.getdstbitmap(), imageloader.getinstance().getmemorycache()); //disccacheutils.removefromcache(data.getdstbitmap(), imageloader.getinstance().getdisccache()); }, throwable -> { //onerror throwable.printstacktrace(); }, () -> { //simple way clear imageloadercache imageloader.getinstance().clearmemorycache(); } );
second way. more reactive...
create dst bitmap observable
:
public observable<bitmap> getdsticonsfromimagebuttonsbyiconurls(){ return observable.from(myimagebuttons) .map(new func1<myimagebutton, string>() { @override public string call(myimagebutton myimagebutton) { return myimagebutton.geticonurl(); } }) .map(new func1<string, bitmap>() { @override public bitmap call(string s) { return imageloader.getinstance().loadimagesync(url, new imagesize(60, 60)); } }); }
or lambdas
:
public observable<bitmap> getdsticonsfromimagebuttonsbyiconurls(){ return observable.from(myimagebuttons) .map(myimagebutton -> myimagebutton.geticonurl()) .map(s -> imageloader.getinstance().loadimagesync(url, new imagesize(60, 60))); }
create src bitmap observable
:
public observable<bitmap> getsrcicons(){ return observable.from(myimagebuttons) .map(new func1<myimagebutton, bitmap>() { @override public bitmap call(myimagebutton myimagebutton) { return ((bitmapdrawable) myimagebutton.getdrawable()).getbitmap(); } }); }
or lambdas
:
public observable<bitmap> getsrcicons(){ return observable.from(myimagebuttons) .map(myimagebutton -> ((bitmapdrawable) myimagebutton.getdrawable()).getbitmap()); }
use operator zip( )
link:
observable .zip( observable.from(myimagebuttons), getdsticonsfromimagebuttonsbyiconurls(), getsrcicons(), new func3<myimagebutton, bitmap, bitmap, myimagebutton>() { @override public myimagebutton call(myimagebutton btn, bitmap dstbitmap, bitmap srcbitmap) { if(dstbitmap != null){ btn.setimagebitmap(bitmaputils.combineimage(srcbitmap, dstbitmap, porterduff.mode.dst_over)); //recycle bitmaps if don't need them dstbitmap.recycle(); srcbitmap.recycle(); } return btn; } }) .subscribe( new action1<myimagebutton>() { @override public void call(myimagebutton myimagebutton) { //do nothing } }, new action1<throwable>() { @override public void call(throwable throwable) { throwable.printstacktrace(); } }, new action0() { @override public void call() { imageloader.getinstance().clearmemorycache(); } });
or use lambdas
:
observable .zip( observable.from(myimagebuttons), getdsticonsfromimagebuttonsbyiconurls(), getsrcicons(), (btn, dstbitmap, srcbitmap) -> { if(dstbitmap != null){ btn.setimagebitmap(bitmaputils.combineimage(srcbitmap, dstbitmap, porterduff.mode.dst_over)); //recycle bitmaps if don't need them dstbitmap.recycle(); srcbitmap.recycle(); } return btn; }) .subscribe( myimagebutton -> { //do nothing }, throwable -> throwable.printstacktrace(), () -> imageloader.getinstance().clearmemorycache());
p.s.
i didn't test examples, should work. if have problems, let me know please.
Comments
Post a Comment