柚子快報(bào)激活碼778899分享:開(kāi)發(fā)語(yǔ)言 RxJava基礎(chǔ)使用
Rx思想
事件從起點(diǎn)流向終點(diǎn)。
過(guò)程中可以對(duì)事件進(jìn)行攔截,攔截時(shí)可以對(duì)事件進(jìn)行處理,處理后將處理后的事件繼續(xù)流向終點(diǎn)。
終點(diǎn)接收上一次處理后的事件。
獲取網(wǎng)絡(luò)圖片并顯示
基礎(chǔ)實(shí)現(xiàn)
使用Observable.just(path) 創(chuàng)建圖片路徑的Observable。
使用map添加攔截,將path轉(zhuǎn)換為Bitmap。
使用map添加攔截,給Bitmap添加水印。
。。。。。隨意添加攔截
使用subscribe訂閱事件,將Bitmap顯示到View中。
private void rxjavaGetBitmap() {
Log.e(TAG,"rxjavaGetBitmap currentThread = "+Thread.currentThread());
//圖片路徑
String path = "https://pic2.zhimg.com/v2-0dda71bc9ced142bf7bb2d6adbebe4f0_r.jpg";
//1 起點(diǎn) 類型是 path 創(chuàng)建Observable 事件是path
Observable.just(path)
//2 攔截 將String->Bitmap 從網(wǎng)絡(luò)中獲取圖片
.map(new Function
@Override
public Bitmap apply(String path) throws Exception {
//根據(jù)path獲取Bitmap
Log.e(TAG,"2-使用path請(qǐng)求Bitmap(String->Bitmap) currentThread = "+Thread.currentThread());
return new HttpURLUtill().getBitmap(path);
}
})
// 上面代碼子線程中執(zhí)行
.subscribeOn(Schedulers.io())
// 下面代碼在主線程執(zhí)行
.observeOn(AndroidSchedulers.mainThread())
// 3 攔截 Bitmap->Bitmap 給圖片添加水印
.map(new Function
@Override
public Bitmap apply(Bitmap bitmap) throws Exception {
Log.e(TAG,"3-給圖片添加水?。˙itmap->Bitmap) currentThread = "+Thread.currentThread());
return bitmap;
}
})
//4 終點(diǎn) 類型是上一個(gè)攔截者的返回類型 添加水印后的Bitmap
.subscribe(new Observer
@Override
public void onSubscribe(Disposable d) {
//代碼執(zhí)行從此處開(kāi)始
Log.e(TAG,"1-subscribe:onSubscribe currentThread = "+Thread.currentThread());
progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.show();
}
@Override
public void onNext(Bitmap value) {
//5 獲取成功 顯示圖片
Log.e(TAG,"4-獲取成功,顯示圖片 currentThread = "+Thread.currentThread());
//顯示圖片
((ImageView)findViewById(R.id.imageview)).setImageBitmap(value);
}
@Override
public void onError(Throwable e) {
//執(zhí)行失敗
Log.e(TAG,"4-失敗 currentThread = "+Thread.currentThread());
if(progressDialog != null){
progressDialog.dismiss();
}
}
@Override
public void onComplete() {
//6 執(zhí)行結(jié)束
Log.e(TAG,"5-完成 currentThread = "+Thread.currentThread());
if(progressDialog != null){
progressDialog.dismiss();
}
}
});
}
中斷
對(duì)于異步執(zhí)行的耗時(shí)操作,需要使用Disposable實(shí)現(xiàn)中斷。
在流程開(kāi)始的時(shí)候,保存Disposable對(duì)象(在Observer中的onSubscribe時(shí)保存Disposable對(duì)象)
在Activity onDestory()時(shí)如果該流程沒(méi)有執(zhí)行完成,需要中斷該流程,否則在執(zhí)行流程結(jié)束更新UI的時(shí)候,會(huì)出現(xiàn)空指針異常。
Rx思想流程
代碼執(zhí)行流程
抽離公共代碼 comose
ObservableTransformer+compose
抽離線程切換和添加水印部分功能為ObservableTransformer,使用compose操作符,使用ObservableTransformer。
/**
* 將部分流程抽離出來(lái)共用,使用ObservableTransformer
* @return
* @param
*/
private
return new ObservableTransformer
@Override
public ObservableSource
return upstream
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.map(new Function
@Override
public UD apply(UD ud) throws Exception {
Log.e(TAG,"3-給圖片添加水?。˙itmap->Bitmap) currentThread = "+Thread.currentThread());
return ud;
}
});
}
};
}
/**
* 抽離部分內(nèi)容為方法
*/
private void rxjavaGetBitmap2() {
Log.e(TAG,"rxjavaGetBitmap currentThread = "+Thread.currentThread());
String path = "https://pic2.zhimg.com/v2-0dda71bc9ced142bf7bb2d6adbebe4f0_r.jpg";
//起點(diǎn) 類型是 path
Observable.just(path)
//攔截 將String->Bitmap
.map(new Function
@Override
public Bitmap apply(String path) throws Exception {
//根據(jù)path獲取Bitmap
Log.e(TAG,"2-使用path請(qǐng)求Bitmap(String->Bitmap) currentThread = "+Thread.currentThread());
return new HttpURLUtill().getBitmap(path);
}
})
.compose(rxud())
//終點(diǎn) 類型是上一個(gè)攔截者的返回類型 Bitmap
.subscribe(new Observer
@Override
public void onSubscribe(Disposable d) {
Log.e(TAG,"1-subscribe:onSubscribe currentThread = "+Thread.currentThread());
progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.show();
}
@Override
public void onNext(Bitmap value) {
//獲取成功 顯示圖片
Log.e(TAG,"4-獲取成功,顯示圖片 currentThread = "+Thread.currentThread());
//顯示圖片
((ImageView)findViewById(R.id.imageview)).setImageBitmap(value);
}
@Override
public void onError(Throwable e) {
Log.e(TAG,"4-失敗 currentThread = "+Thread.currentThread());
if(progressDialog != null){
progressDialog.dismiss();
}
}
@Override
public void onComplete() {
//第四步 結(jié)束執(zhí)行
Log.e(TAG,"5-完成 currentThread = "+Thread.currentThread());
if(progressDialog != null){
progressDialog.dismiss();
}
}
});
}
簡(jiǎn)化觀察者 Consumer
Observer-> Consumer
/**
* 簡(jiǎn)化訂閱者
*/
private void rxjavaGetBitmap3() {
Log.e(TAG,"rxjavaGetBitmap currentThread = "+Thread.currentThread());
String path = "https://pic2.zhimg.com/v2-0dda71bc9ced142bf7bb2d6adbebe4f0_r.jpg";
//起點(diǎn) 類型是 path
Observable.just(path)
//攔截 將String->Bitmap
.map(new Function
@Override
public Bitmap apply(String path) throws Exception {
//根據(jù)path獲取Bitmap
Log.e(TAG,"2-使用path請(qǐng)求Bitmap(String->Bitmap) currentThread = "+Thread.currentThread());
return new HttpURLUtill().getBitmap(path);
}
})
.compose(rxud())
.doOnSubscribe(new Consumer
@Override
public void accept(Disposable disposable) throws Exception {
Log.e(TAG,"1-subscribe:onSubscribe currentThread = "+Thread.currentThread());
progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.show();
}
})
//終點(diǎn) 類型是上一個(gè)攔截者的返回類型 Bitmap
.subscribe(new Consumer
@Override
public void accept(Bitmap bitmap) throws Exception {
//第三步 獲取成功 顯示圖片
Log.e(TAG,"4-獲取成功,顯示圖片 currentThread = "+Thread.currentThread());
//顯示圖片
((ImageView)findViewById(R.id.imageview)).setImageBitmap(bitmap);
if(progressDialog != null){
progressDialog.dismiss();
}
}
}, new Consumer
@Override
public void accept(Throwable throwable) throws Exception {
Log.e(TAG,"4-失敗 currentThread = "+Thread.currentThread());
if(progressDialog != null){
progressDialog.dismiss();
}
}
});
}
RxJava+Retrofit
單個(gè)接口
請(qǐng)求執(zhí)行類型使用RxJava的Observable,網(wǎng)絡(luò)請(qǐng)求后返回的直接是RxJava的被觀察者Observable。
相當(dāng)于通過(guò)Observable.just(path)獲取到Observable。
然后可以對(duì)Observable執(zhí)行攔截、訂閱。
Retrofit Api接口類:使用玩Android 開(kāi)放API 玩Android 開(kāi)放API-玩Android - wanandroid.com
public interface NetWorkApi {
//獲取項(xiàng)目分類
@GET("project/tree/json")
Observable
//獲取項(xiàng)目分類下的信息
@GET("project/list/{pageIndex}/json")
Observable
}
獲取到項(xiàng)目分類信息
//獲取Retrofit
public Retrofit getRetrofit(){
return new Retrofit.Builder()
.baseUrl("https://www.wanandroid.com/")
//Gson解析
.addConverterFactory(GsonConverterFactory.create())
//Rxjava CallAdapter
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
}
public void getProjectInfo(View view) {
//獲取項(xiàng)目分類
getRetrofit().create(NetWorkApi.class) //獲取Retrofit api實(shí)現(xiàn)類
.getProject() //獲取Observable
.subscribeOn(Schedulers.io()) //上面代碼在子線程中執(zhí)行
.observeOn(AndroidSchedulers.mainThread()) //下面代碼在主線程中執(zhí)行
.subscribe(new Consumer
@Override
public void accept(ProjectBean projectBean) throws Exception {
Log.e(TAG, projectBean.toString());
}
});
}
多個(gè)接口網(wǎng)絡(luò)嵌套 flatMap
順序請(qǐng)求兩個(gè)接口的數(shù)據(jù)后更新UI。
網(wǎng)絡(luò)嵌套的方法。
//網(wǎng)絡(luò)嵌套寫法
@SuppressLint("CheckResult")
private void networkNesting(){
//獲取項(xiàng)目分類
getRetrofit().create(NetWorkApi.class)
.getProject()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer
@Override
public void accept(ProjectBean projectBean) throws Exception {
Log.e(TAG, projectBean.toString());
for (ProjectBean.DataBean datum : projectBean.getData()) {
//根據(jù)分類id獲取項(xiàng)目列表數(shù)據(jù)
getRetrofit().create(NetWorkApi.class)
.getProjectItem(1, datum.getId())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer
@Override
public void accept(ProjectItemBean projectItemBean) throws Exception {
Log.e(TAG, projectItemBean.toString());
}
});
}
}
});
}
使用flatMap解決上述網(wǎng)絡(luò)嵌套問(wèn)題,將一個(gè)事件變?yōu)槎鄠€(gè)事件。
ps:任何一個(gè)位置發(fā)生異常,整個(gè)流程結(jié)束執(zhí)行。
@SuppressLint("CheckResult")
private void noNesting(){
//獲取項(xiàng)目分類
getRetrofit().create(NetWorkApi.class)
.getProject()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
//循環(huán)項(xiàng)目分類 1個(gè)Observable轉(zhuǎn)多個(gè)Observable
.flatMap(new Function
@Override
public ObservableSource
return Observable.fromIterable(projectBean.getData());
}
})
//根據(jù)項(xiàng)目分類id請(qǐng)求項(xiàng)目分類信息
.flatMap(new Function
@Override
public ObservableSource
Log.e(TAG, dataBean.toString());
return getRetrofit().create(NetWorkApi.class).getProjectItem(1, dataBean.getId());
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer
@Override
public void accept(ProjectItemBean projectItemBean) throws Exception {
//獲得項(xiàng)目分類信息
Log.e(TAG, projectItemBean.toString());
}
}, new Consumer
@Override
public void accept(Throwable throwable) throws Exception {
Log.e(TAG, "異常 一旦發(fā)生異常,整個(gè)鏈?zhǔn)秸{(diào)用就結(jié)束了");
}
});
}
多個(gè)接口過(guò)程中更新UI doOnNext
順序請(qǐng)求兩個(gè)接口,并在每個(gè)接口請(qǐng)求結(jié)束后更新相應(yīng)的UI。
使用doOnNext操作符實(shí)現(xiàn)。
private void updateProjectAndProjectItemInfo() {
getRetrofit().create(NetWorkApi.class)
.getProject()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
//獲取到項(xiàng)目分類信息后,執(zhí)行UI操作
.doOnNext(new Consumer
@Override
public void accept(ProjectBean dataBean) throws Exception {
((TextView) findViewById(R.id.tv_project)).setText("我被更新了");
}
})
.observeOn(Schedulers.io())
//循環(huán)項(xiàng)目分類 1個(gè)Observable轉(zhuǎn)多個(gè)Observable
.flatMap(new Function
@Override
public ObservableSource
return Observable.fromIterable(projectBean.getData());
}
})
//根據(jù)項(xiàng)目分類id請(qǐng)求項(xiàng)目分類信息
.flatMap(new Function
@Override
public ObservableSource
Log.e(TAG, dataBean.toString());
return getRetrofit().create(NetWorkApi.class).getProjectItem(1, dataBean.getId());
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer
@Override
public void accept(ProjectItemBean projectItemBean) throws Exception {
//獲得項(xiàng)目分類信息
Log.e(TAG, projectItemBean.toString());
((TextView) findViewById(R.id.tv_project_item)).setText("我被更新了");
}
}, new Consumer
@Override
public void accept(Throwable throwable) throws Exception {
Log.e(TAG, "異常 一旦發(fā)生異常,整個(gè)鏈?zhǔn)秸{(diào)用就結(jié)束了");
}
});
}
防抖
使用RxView庫(kù)。
柚子快報(bào)激活碼778899分享:開(kāi)發(fā)語(yǔ)言 RxJava基礎(chǔ)使用
相關(guān)閱讀
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場(chǎng)。
轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。