RxJava梳理

ljwx9527發表於2019-02-18

響應式程式設計

什麼是響應式程式設計
通過非同步資料流來構建事務關係的程式設計模型
RxJava梳理

舉例
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[])方法來建立自己

map和flatmap的原理

RxJava2常用操作符教程

為什麼避免使用RxBus

粘性事件:就是可以接收訂閱之前的事件

ViewMode+LiveData 模式
編譯原理,資料結構,作業系統,計算機組成原理
KMP演算法

相關文章