響應式程式設計
什麼是響應式程式設計
通過非同步和資料流來構建事務關係的程式設計模型
舉例
app啟動時, 先初始化sdk, 初始化資料庫, 登入, 都成功後跳轉首頁, 他們都需要耗時操作
Observable.just(context)
.map((context)->{login(getUserId(context))})
.map((context)->{initSDK(context)})
.map((context)->{initDatabase(context)})
.subscribeOn(Schedulers.newThread())
.subscribe((context)->{startActivity()})
複製程式碼
- 其實,這種寫法並不是響應式的,本質上還是建立一個子執行緒,然後順序呼叫程式碼最後跳轉頁面。這種程式碼依然沒有忠實反映業務之間的關係
Observable obserInitSDK=Observable.create((context)->{ initSDK(context) }).subscribeOn(Schedulers.newThread())
Observable obserInitDB=Observable.create((context)->{ initDatabase(context) }).subscribeOn(Schedulers.newThread())
Observable obserLogin=Observable.create((context)->{ login(getUserId(context)) })
.map((isLogin)->{ return Context() })
.subscribeOn(Schedulers.newThread())
Observable observable = Observable.merge(obserInitSDK,obserInitDB,obserLogin)
observable.subscribe(()->{startActivity()})
複製程式碼
- 大家應該能很明顯看到兩段程式碼的區別,第二段程式碼完全遵照了業務之間客觀存在的關係,可以說程式碼和業務關係是完全對應的。
- 那麼這帶來了什麼好處呢?當initSDK,initDB,Login都是耗時較長的操作時,遵照業務關係編寫響應式程式碼可以極大的提高程式的執行效率,降低阻塞。
- 理論上講,遵照業務關係執行的程式碼在執行效率上是最優的
RxJava常用用法
建立被觀察者的幾種方式
//1
Observable switcher = Observable.create(new Observable.OnSubscribe<String>(){
@Override
public void call(Subscriber<? super String> subscriber) {
subscriber.onNext("On");
subscriber.onCompleted();
}
});
//2
Observable switche r= Observable.just("On","Off","On","On");
//3
String [] kk={"On","Off","On","On"};
Observable switcher = Observable.from(kk);
複製程式碼
建立觀察者的幾種方式
//1
Subscriber light = new Subscriber<String>() {
@Override
public void onCompleted() {
//被觀察者的onCompleted()事件會走到這裡;
Log.d("DDDDDD","結束觀察...\n");
}
@Override
public void onError(Throwable e) {
//出現錯誤會呼叫這個方法
}
@Override
public void onNext(String s) {
//處理傳過來的onNext事件
Log.d("DDDDD","handle this---"+s)
}
//2 偷懶(非正式寫法)
Action1 light = new Action1<String>() {
@Override
public void call(String s) {
Log.d("DDDDD","handle this---"+s)
}
}
複製程式碼
將兩者訂閱在一起
switcher.subscribe(light);
複製程式碼
之所以“開關訂閱檯燈”, 是為了保證流式API呼叫風格
RxJava常用操作符
Map型別變換
Observable.just(getFilePath()
.subscribeOn(Schedulers.newThread()) //指定了被觀察者執行的執行緒環境
.observeOn(Schedulers.io()) //將接下來執行的執行緒環境指定為io執行緒
//使用map操作來完成型別轉換
.map(new Func1<String, Bitmap>() {
@Override
public Bitmap call(String s) {
return createBitmapFromPath(s); //方法,是一個極其耗時的操作
}
})
.observeOn(AndroidSchedulers.mainThread()) //將後面執行的執行緒環境切換為主執行緒
.subscribe(
new Subscriber<Bitmap>() { //建立觀察者,作為事件傳遞的終點處理事件
@Override
public void onNext(Bitmap s) {
showBitmap(s) //處理事件
}
);
複製程式碼
FlatMap
//建立被觀察者,獲取所有班級
Observable.from(getSchoolClasses())
.flatMap(new Func1<SingleClass, Observable<Student>>() {
@Override
public Observable<Student> call(SingleClass singleClass) {
//將每個班級的所有學生作為一列表包裝成一列Observable<Student>,將學生一個一個傳遞出去
return Observable.from(singleClass.getStudents()); //返回Observable
}
})
.subscribe(
//建立觀察者,作為事件傳遞的終點處理事件
new Subscriber<Student>() {
@Override
public void onNext(Student student) {
//接受到每個學生類
Log.d("DDDDDD",student.getName())
}
);
複製程式碼
FlatMap可以再次包裝新的Observable,而每個Observable都可以使用from(T[])方法來建立自己
粘性事件:就是可以接收訂閱之前的事件
ViewMode+LiveData 模式
編譯原理,資料結構,作業系統,計算機組成原理
KMP演算法