* 一種幫助作異步的框架. 相似於 AsyncTask. 但其靈活性和擴展性遠遠強於前者.
* 主頁: https://github.com/ReactiveX/RxJavajava
* 中文資料:
* https://github.com/lzyzsd/Awesome-RxJavareact
* https://www.zhihu.com/question/35511144android
* 用途:
* 異步操做
* 在程序邏輯異常複雜的狀況下,仍然可讓代碼的邏輯保持簡潔git
* 配置: 添加依賴:
* compile 'io.reactivex:rxjava:1.1.3'
* compile 'io.reactivex:rxandroid:1.1.0'github
基本概念:
1. 被觀察者: Observable
* 做用: 決定何時觸發事件以及觸發怎樣的事件
* 建立方法:
* Observable.just(T...) 參數爲單個的
* Observable.from(T[]) / Observable.from(Iterable<? extends T>) 參數爲數組或Iterable
2. 觀察者: Observer
* 做用: 當事件觸發的時候將有怎樣的行爲
* 實現類有Observer / Subscriber
3. 訂閱: subscribe
* 做用: 把Observable和Observer關聯起來
* 方法:
* observable.subscribe(observer);
* observable.subscribe(subscriber);
4. 事件:
* onNext():普通事件
* onCompleted():事件隊列完結
* onError(): 事件隊列異常
* 須要注意的是onCompleted()和onError()是互斥的.調用了其中一個就不該該觸發另外一個.數據庫
一、建立Observable對象數組
Observable<String> myObservable = Observable.create( new Observable.OnSubscribe<String>() { @Override public void call(Subscriber<? super String> sub) { sub.onNext("Hello, world!"); //通知訂閱者 sub.onCompleted(); } } );
二、建立一個Subscriber來處理Observable對象發出的字符串
網絡
Subscriber<String> mySubscriber = new Subscriber<String>() { @Override public void onNext(String s) { System.out.println(s); } @Override public void onCompleted() { } @Override public void onError(Throwable e) { } };
三、將定義的myObservable對象和mySubscriber對象關聯起來,這樣就完成了subscriber對observable的訂閱。框架
myObservable.subscribe(mySubscriber);
簡化版:異步
Observable<String> myObservable = Observable.just("Hello, world!"); Action1<String> onNextAction = new Action1<String>() { @Override public void call(String s) { System.out.println(s); } }; myObservable.subscribe(onNextAction);
最終簡化版:
Observable.just("Hello, world!") .subscribe(new Action1<String>() { @Override public void call(String s) { System.out.println(s); } });
示例代碼:
1. 現有一個數組 String[] arr ={"afdsa", "bfdsa", "cfda"}, 把其中以字母"a"開頭的字符串找出來並加上"from Alpha",最後打印出新的字符串的長度
Observable .from(arr) .filter(new Func1<String, Boolean>() { @Override public Boolean call(String s) { return s.startsWith("a"); } }) .map(new Func1<String, String>() { @Override public String call(String s) { return s + " from Alpha"; } }) .subscribe(new Action1<String>() { @Override public void call(String s) { System.out.println("Rxjava:" + s.length()); } }); //原始Java代碼 for (int i = 0; i < arr.length; i++) { String temp = arr[i]; if (temp.startsWith("a")) { temp += " from Alpha"; System.out.println("Normal:" + temp.length()); } }
由指定的一個 drawable 文件 id 取得圖片,並顯示在 ImageView 中,並在出現異常的時候打印 Toast 報錯:
ImageView iv = (ImageView) findViewById(R.id.imageView); Observable.just(R.mipmap.ic_launcher) .subscribeOn(Schedulers.io()) //運行在子線程中 .map(new Func1<Integer, Drawable>() { @Override public Drawable call(Integer integer) { return getResources().getDrawable(integer); } }) .observeOn(AndroidSchedulers.mainThread()) //運行在主線程中 .subscribe(new Action1<Drawable>() { @Override public void call(Drawable drawable) { iv.setImageDrawable(drawable); } }); }
6. Scheduler
* 做用: 控制線程.指定某一段代碼在那個線程裏運行.
* 內置的Scheduler:
* Schedulers.immediate(): 直接在當前線程運行,至關於不指定線程。這是默認的 Scheduler。
* Schedulers.newThread(): 老是啓用新線程,並在新線程執行操做。
* Schedulers.io(): I/O 操做(讀寫文件、讀寫數據庫、網絡信息交互等)所使用的 Scheduler。行爲模式和 newThread() 差很少,區別在於 io() 的內部實現是是用一個無數量上限的線程池,能夠重用空閒的線程,所以多數狀況下 io() 比 newThread() 更有效率。不要把計算工做放在 io() 中,能夠避免建立沒必要要的線程。
* Schedulers.computation(): 計算所使用的 Scheduler。這個計算指的是 CPU 密集型計算,即不會被 I/O 等操做限制性能的操做,例如圖形的計算。這個 Scheduler 使用的固定的線程池,大小爲 CPU 核數。不要把 I/O 操做放在 computation() 中,不然 I/O 操做的等待時間會浪費 CPU。
* AndroidSchedulers.mainThread(): Android專用,它指定的操做將在 Android 主線程運行。
* 指定線程的方法:
* Observable.subscribeOn():指定 subscribe() 所發生的線程。
subscribeOn(Schedulers.io())
* Observable.observeOn():指定 Subscriber 所運行在的線程。
observeOn(AndroidSchedulers.mainThread())
7. 數據變換:
* 做用: 就是將事件序列中的對象或整個序列進行加工處理,轉換成不一樣的事件或事件序列
* Observable.map: 一對一的轉換
private void simpleDemo() { Observable .just(R.mipmap.ic_launcher) .map(new Func1<Integer, Drawable>() { @Override public Drawable call(Integer integer) { return getResources().getDrawable(integer); } }) .subscribe(new Action1<Drawable>() { @Override public void call(Drawable drawable) { imageView.setImageDrawable(drawable); } }); }