RxJava
RxJava說到底,它就是一個實作異步操作的庫,但是在Android開發中,我們有現成的AsyncTask 或Handler來實作異步,為什么還需要它呢?RxJava是有好處的,它就好在邏輯簡潔,好在那把什么復雜邏輯都能串成一條線的簡潔
先附上git地址:https://github.com/ReactiveX/RxAndroid
原理淺析
RxJava 的異步實作,是通過一種擴展的觀察者模式來實作的
RxJava 的觀察者模式:
Observable (被觀察者)、 Observer (觀察者)、 subscribe (訂閱)、事件,Observable 和 Observer 通過 subscribe() 方法實作訂閱關系,從而 Observable 可以在需要的時候發出事件來通知 Observer,與傳統觀察者模式不同, RxJava 的事件回呼方法除了普通事件 onNext()之外,還定義了兩個特殊的事件:onCompleted() 和 one rror()
(1)onCompleted(): 事件佇列完結,RxJava 不僅把每個事件單獨處理,還會把它們看做一個佇列,當不會再有新的 onNext() 發出時,需要觸發 onCompleted() 方法作為標志
(2)onError(): 事件佇列例外,在事件處理程序中出例外時,onError() 會被觸發,同時佇列自動終止,不允許再有事件發出
onCompleted() 和 one rror() 二者也是互斥的,即在佇列中呼叫其中一個,就不會再呼叫另一個

基本實作
方式一
(1)創建 Observer,它決定事件觸發的時候將有怎樣的行為
Observer<Integer> observer = new Observer<Integer>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
//觀察者接收事件前,默認最先呼叫復寫onSubscribe
}
@Override
public void onNext(@NonNull Integer s) {
//當被觀察者生產Next事件和觀察者接收到時,會呼叫該復寫方法進行回應
}
@Override
public void onError(@NonNull Throwable e) {
//當被觀察者生產Error事件和觀察者接收到時,會呼叫該復寫方法進行回應
}
@Override
public void onComplete() {
//當被觀察者生產Complete事件和觀察者接收到時,會呼叫該復寫方法 進行回應
}
};
(2) 創建Observable,它決定什么時候觸發事件以及觸發怎樣的事件
Observable observable = Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(@NonNull ObservableEmitter<Integer> emitter) throws Throwable {
//通過ObservableEmitter類物件產生事件并通知觀察者
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
emitter.onComplete();
}
});
(3)通過訂閱(Subscribe)連接觀察者和被觀察者
observable.subscribe(observer);
方式二:基于事件流的鏈式呼叫
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(@NonNull ObservableEmitter<Integer> emitter) throws Throwable {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
emitter.onComplete();
}
}).subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
}
@Override
public void onNext(@NonNull Integer integer) {
Log.d("jay", integer.toString());
}
@Override
public void onError(@NonNull Throwable e) {
}
@Override
public void onComplete() {
}
});
方式三:簡便式的觀察者模式
Observable.just("hello world").subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Throwable {
Log.d("jay", s);
}
});
(4)可采用 Disposable.dispose() 切斷觀察者與被觀察者之間的連接
private Disposable disposable;
Observer<Integer> observer = new Observer<Integer>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
//觀察者接收事件前,默認最先呼叫復寫onSubscribe
disposable = d;
}
@Override
public void onNext(@NonNull Integer s) {
//當被觀察者生產Next事件和觀察者接收到時,會呼叫該復寫方法進行回應
if (s == 2) {
disposable.dispose();
}
Log.d("jay",s.toString());
}
@Override
public void onError(@NonNull Throwable e) {
//當被觀察者生產Error事件和觀察者接收到時,會呼叫該復寫方法進行回應
}
@Override
public void onComplete() {
//當被觀察者生產Complete事件和觀察者接收到時,會呼叫該復寫方法 進行回應
}
};
retrofit
retrofit基于okhttp封裝的網路請求框架,網路請求的作業本質上是 OkHttp 完成,而retrofit 僅負責網路請求介面的封裝,我覺得retrofit最大的特點就是解耦
先附上github地址:https://github.com/square/retrofit
(1)依賴
implementation "com.squareup.retrofit2:retrofit:2.9.0"
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
(2)創建網路請求介面
public interface HttpList {
@FormUrlEncoded
@POST(HttpUrl.JOUR_LIST)
Call<JourBean> httpsend(@Field("companyid") String companyid, @Field("index") String index,
@Field("size") String size, @Field("keyword") String keyword,
@Field("status") String status, @Field("classno") String classno,
@Field("checkdate") String checkdate);
}
(3)請求網路
//baseUrl不能為空,且強制要求必需以斜杠結尾
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(HttpUrl.BaseApi)
.addConverterFactory(GsonConverterFactory.create())
.callbackExecutor(Executors.newSingleThreadExecutor())
.build();
HttpList httpList = retrofit.create(HttpList.class);
Call<JourBean> call = httpList.httpsend(companyid, index, size, keyword, status, classno, checkdate);
call.enqueue(new Callback<JourBean>() {
@Override
public void onResponse(Call<JourBean> call, Response<JourBean> response) {
JourBean bean = response.body();
}
@Override
public void onFailure(Call<JourBean> call, Throwable t) {
}
});
這樣,我們就完成了一個post請求,是不是特別簡單,不過,只知道怎么使用還不夠,下面來簡單講講Retrofit的原理吧
Retrofit的精髓就在于內部的動態代理模式(JDK的動態代理)
首先,通過Builder創建Retrofit物件,在create方法中,通過JDK動態代理的方式,生成實作類,在呼叫介面方法時,會觸發InvocationHandler的invoke方法,將介面的空方法轉換成ServiceMethod,然后生成okhttp請求,通過callAdapterFactory找到對應的執行器,最后通過ConverterFactory將回傳資料決議成JavaBean,使用者只需要關心請求引數,內部實作由retrofit封裝完成,底層請求還是基于okhttp實作的
ServiceMethod:核心處理類,決議介面中定義的請求方法引數和注解,通過toCall方法將其轉換成okhttp的call物件,有了Call物件,就可以發送請求了
callAdapterFactories:通過calladapter將原始Call進行封裝,找到對應的執行器
converterFactories:資料決議器Converter,將response通過converterFactory轉換成對應的JavaBean資料形式
RxJava和Retrofit的結合使用
(1)加入依賴
implementation "com.squareup.retrofit2:retrofit:2.9.0"
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.5.0'
implementation 'io.reactivex.rxjava2:rxjava:2.2.9'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
(2)修改網路請求介面
public interface HttpList {
@FormUrlEncoded
@POST(HttpUrl.JOUR_LIST)
Observable<JourBean> httpsend(@Field("companyid") String companyid, @Field("index") String index,
@Field("size") String size, @Field("keyword") String keyword,
@Field("status") String status, @Field("classno") String classno,
@Field("checkdate") String checkdate);
}
(3)RxJava+Retrofit結合式請求網路
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(HttpUrl.BaseApi)
.addConverterFactory(GsonConverterFactory.create())
.callbackExecutor(Executors.newSingleThreadExecutor())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
HttpList httpList = retrofit.create(HttpList.class);
httpList.httpsend(companyid, index, size, keyword, status, classno, checkdate)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<JourBean>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
}
@Override
public void onNext(@NonNull JourBean jourBean) {
Log.d("jayonNext", jourBean.toString());
}
@Override
public void onError(@NonNull Throwable e) {
Log.d("jayonError", e.getMessage());
}
@Override
public void onComplete() {
Log.d("jay", "請求完成");
}
});
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/187687.html
標籤:其他
上一篇:安卓大變天!ButterKnife被棄用:Resource IDs will be non-final in Android Gradle Plugin version 5.0
