2018-01-09 RxJava、RxAndroid 學習

介紹

a library for composing asynchronous and event-based programs using observable sequences for the Java VM -------一個在 Java VM 上使用可觀測的序列來組成異步的、基于事件的程序的庫

使用

1、關聯

compile 'io.reactivex:rxjava:1.0.14'

compile 'io.reactivex:rxandroid:1.0.1'

2、簡單示例

public void test01(){

? ? ? ? Log.e(tag,"------------test01-----------" +

? ? ? ? ? ? ? ? "\n----------簡單實例01---------");

? ? ? ? //創建被觀察者

? ? ? ? Observable observable = Observable.create(new Observable.OnSubscribe() {

? ? ? ? ? ? @Override

? ? ? ? ? ? public void call(Subscriber subscriber) {

? ? ? ? ? ? ? ? //調用觀察者的回調

? ? ? ? ? ? ? ? subscriber.onNext("我是");

? ? ? ? ? ? ? ? subscriber.onNext("RxJava");

? ? ? ? ? ? ? ? subscriber.onNext("簡單示例");

? ? ? ? ? ? ? ? subscriber.onError(new Throwable("出錯了"));

? ? ? ? ? ? ? ? subscriber.onCompleted();

? ? ? ? ? ? }

? ? ? ? });

? ? ? ? //創建觀察者

? ? ? ? Observer observer = new Observer() {

? ? ? ? ? ? @Override

? ? ? ? ? ? public void onCompleted() {

? ? ? ? ? ? ? ? Log.e(tag,"onCompleted");

? ? ? ? ? ? }

? ? ? ? ? ? @Override

? ? ? ? ? ? public void onError(Throwable e) {

? ? ? ? ? ? ? ? Log.e(tag,e.getMessage());

? ? ? ? ? ? }

? ? ? ? ? ? @Override

? ? ? ? ? ? public void onNext(String s) {

? ? ? ? ? ? ? ? Log.e(tag,s);

? ? ? ? ? ? }

? ? ? ? };

? ? ? ? //注冊,是的觀察者和被觀察者關聯,將會觸發OnSubscribe.call方法

? ? ? ? observable.subscribe(observer);

? ? }

運行結果:

? ? =====>: ------------test01-----------

? ? ? ? ? ? ----------簡單實例01---------

? ? =====>: 我是

? ? =====>: RxJava

? ? =====>: 簡單示例

? ? =====>: 出錯了

Observable是被觀察者,通過create創建(還有其他方式,后面將會講到),傳入一個OnSubscribe對象,當Observable調用subscribe進行注冊觀察者時,OnSubscribe的call方法會觸發。Observer是觀察者,他有三個回調方法:

onNext? ? ? :接受到一個事件

onCompleted :接受完事件后調用,只會調用一次

onError? ? :發生錯誤時調用,并停止接受事件,調用一次

onCompleted和onError不會同時調用,只會調用其中之一

觀察者除了使用Observer,還可以使用Subscriber,它跟?Observer作用一樣,如下:

public void test02(){

? ? ? ? Log.e(tag,"------------test02-----------" +

? ? ? ? ? ? ? ? "\n----------簡單實例02---------");

? ? ? ? //創建被觀察者

? ? ? ? Observable observable = Observable.create(new Observable.OnSubscribe() {

? ? ? ? ? ? @Override

? ? ? ? ? ? public void call(Subscriber subscriber) {

? ? ? ? ? ? ? ? //調用觀察者的回調

? ? ? ? ? ? ? ? subscriber.onNext("我是");

? ? ? ? ? ? ? ? subscriber.onNext("RxJava");

? ? ? ? ? ? ? ? subscriber.onNext("簡單示例");

? ? ? ? ? ? ? ? subscriber.onCompleted();

? ? ? ? ? ? ? ? subscriber.onError(new Throwable("出錯了"));

? ? ? ? ? ? }

? ? ? ? });

? ? ? ? //創建觀察者

? ? ? ? Subscriber subscriber = new Subscriber() {

? ? ? ? ? ? @Override

? ? ? ? ? ? public void onStart() {

? ? ? ? ? ? ? ? Log.e(tag,"onStart");

? ? ? ? ? ? }

? ? ? ? ? ? @Override

? ? ? ? ? ? public void onCompleted() {

? ? ? ? ? ? ? ? Log.e(tag,"onCompleted");

? ? ? ? ? ? }

? ? ? ? ? ? @Override

? ? ? ? ? ? public void onError(Throwable e) {

? ? ? ? ? ? ? ? Log.e(tag,e.getMessage());

? ? ? ? ? ? }

? ? ? ? ? ? @Override

? ? ? ? ? ? public void onNext(String s) {

? ? ? ? ? ? ? ? Log.e(tag,s);

? ? ? ? ? ? }

? ? ? ? };

? ? ? ? //注冊,使得觀察者和被觀察者關聯,將會觸發OnSubscribe.call方法

? ? ? ? observable.subscribe(subscriber);

? ? }

運行結果

=====>: ------------test02-----------

? ? ? ? ----------簡單實例02---------

=====>: onStart

=====>: 我是

=====>: RxJava

=====>: 簡單示例

=====>: onCompleted

這里只是多了一個onStart方法 ,這個方法會在Observable調用方法subscribe注冊觀察者時調用一次,表明事件要開始了。

因為Subscriber只是對Observer的擴展,用法都一樣,所以后面例子都用?Subscriber做觀察者。

3、Observable的創建

前面簡單的例子中,創建Observable是通過create方法,當然還有其他方法,體驗一下吧:

public void test03(){

? ? ? ? Log.e(tag,"------------test03-----------" +

? ? ? ? ? ? ? ? "\n----------創建觀察者01---------");

? ? ? ? Integer[] ints={1,2,3,4};

? ? ? ? Observable.from(ints).subscribe(new Subscriber() {

? ? ? ? ? ? @Override

? ? ? ? ? ? public void onCompleted() {

? ? ? ? ? ? ? ? Log.e(tag,"onCompleted");

? ? ? ? ? ? }

? ? ? ? ? ? @Override

? ? ? ? ? ? public void onError(Throwable e) {

? ? ? ? ? ? ? ? Log.e(tag,e.getMessage());

? ? ? ? ? ? }

? ? ? ? ? ? @Override

? ? ? ? ? ? public void onNext(Integer integer) {

? ? ? ? ? ? ? ? Log.e(tag,integer+"");

? ? ? ? ? ? }

? ? ? ? });

? ? }

運行結果

=====>: ------------test03-----------

? ? ? ? ----------創建觀察者01---------

=====>: 1

=====>: 2

=====>: 3

=====>: 4

=====>: onCompleted

from方法將傳入的數組或 Iterable 拆分成具體對象后,依次發送出來。

public void test04(){

? ? ? ? Log.e(tag,"------------test04-----------" +

? ? ? ? ? ? ? ? "\n----------創建被觀察者02---------");

? ? ? ? Observable.just(1,2,3,4).subscribe(new Subscriber() {

? ? ? ? ? ? @Override

? ? ? ? ? ? public void onCompleted() {

? ? ? ? ? ? ? ? Log.e(tag,"onCompleted");

? ? ? ? ? ? }

? ? ? ? ? ? @Override

? ? ? ? ? ? public void onError(Throwable e) {

? ? ? ? ? ? ? ? Log.e(tag,e.getMessage());

? ? ? ? ? ? }

? ? ? ? ? ? @Override

? ? ? ? ? ? public void onNext(Integer integer) {

? ? ? ? ? ? ? ? Log.e(tag,integer+"");

? ? ? ? ? ? }

? ? ? ? });

? ? }

運行結果

=====>: ------------test04-----------

? ? ? ? ----------創建被觀察者02---------

=====>: 1

=====>: 2

=====>: 3

=====>: 4

=====>: onCompleted

和from方法一樣,just(T...): 將傳入的參數依次發送出來。

4、觀察者的其他可用形式

觀察者Subscriber和Observer都需要寫三個回調,有時候我們只關系其中一個回調,或者兩個

public void test05(){

? ? ? ? Log.e(tag,"------------test05-----------" +

? ? ? ? ? ? ? ? "\n----------創建觀察者其他形式---------");

? ? ? ? String[] strs={"aa","bb","cc"};

? ? ? ? Action1 onNextAction = new Action1() {

? ? ? ? ? ? // onNext()

? ? ? ? ? ? @Override

? ? ? ? ? ? public void call(String s) {

? ? ? ? ? ? ? ? Log.d(tag, s);

? ? ? ? ? ? }

? ? ? ? };

? ? ? ? Action1 onErrorAction = new Action1() {

? ? ? ? ? ? // onError()

? ? ? ? ? ? @Override

? ? ? ? ? ? public void call(Throwable throwable) {

? ? ? ? ? ? ? Log.e(tag,throwable.getMessage());

? ? ? ? ? ? }

? ? ? ? };

? ? ? ? Action0 onCompletedAction = new Action0() {

? ? ? ? ? ? // onCompleted()

? ? ? ? ? ? @Override

? ? ? ? ? ? public void call() {

? ? ? ? ? ? ? ? Log.d(tag, "completed");

? ? ? ? ? ? }

? ? ? ? };

? ? ? ? Observable observable = Observable.from(strs);

? ? ? ? // 自動創建 Subscriber ,并使用 onNextAction 來定義 onNext()

? ? ? ? observable.subscribe(onNextAction);

? ? ? ? // 自動創建 Subscriber ,并使用 onNextAction 和 onErrorAction 來定義 onNext() 和 onError()

? ? ? ? observable.subscribe(onNextAction, onErrorAction);

? ? ? // 自動創建 Subscriber ,并使用 onNextAction、 onErrorAction 和 onCompletedAction 來定義 onNext()、 onError() 和 onCompleted()

? ? ? ? observable.subscribe(onNextAction, onErrorAction, onCompletedAction);

? ? }

這里使用了Action1和Action0, Action0 是 RxJava 的一個接口,它只有一個方法 call(),這個方法是無參無返回值的;由于 onCompleted() 方法也是無參無返回值的,因此 Action0 可以被當成一個包裝對象,將 onCompleted() 的內容打包起來將自己作為一個參數傳入 subscribe() 以實現不完整定義的回調。 Action1 也是一個接口,它同樣只有一個方法 call(T param),這個方法也無返回值,但有一個參數;與 Action0 同理,由于 onNext(T obj) 和 onError(Throwable error) 也是單參數無返回值的,因此 Action1 可以將 onNext(obj) 和 onError(error) 打包起來傳入 subscribe() 以實現不完整定義的回調。事實上,雖然 Action0 和 Action1 在 API 中使用最廣泛,但 RxJava 是提供了多個 ActionX 形式的接口 (例如 Action2, Action3) 的,它們可以被用以包裝不同的無返回值的方法。

5、線程調度

RxJava遵循線程不變原則,在不做特殊處理的情況下,在哪個線程調用 subscribe(),就在哪個線程生產事件;在哪個線程生產事件,就在哪個線程消費事件。如果需要切換線程,就需要用到 Scheduler (調度器)

? ? public void test06(){

? ? ? ? Log.e(tag, "------------test06-----------" +

? ? ? ? ? ? ? ? "\n----------線程調度---------");

? ? ? ? //從網絡上根據用戶id,請求對應用戶,并顯示用戶積分到界面

? ? ? ? Observable.create(new Observable.OnSubscribe() {

? ? ? ? ? ? @Override

? ? ? ? ? ? public void call(Subscriber subscriber) {

? ? ? ? ? ? ? ? int id=111;

? ? ? ? ? ? ? ? UserInfo userinfo=getUserInfoFromNet(id);

? ? ? ? ? ? ? ? subscriber.onNext(userinfo.points);

? ? ? ? ? ? }

? ? ? ? }).subscribeOn(Schedulers.io())//事件產生在io線程

? ? ? ? ? .observeOn(AndroidSchedulers.mainThread())//消耗事件在主線程

? ? ? ? ? .subscribe(new Action1() {

? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? public void call(Integer points) {

? ? ? ? ? ? ? ? ? Log.e(tag, "顯示用戶積分:" + points);

? ? ? ? ? ? ? }

? ? ? ? ? });

? ? }

? ? //模擬從網絡請求

? ? private UserInfo getUserInfoFromNet(int id) {

? ? ? ? UserInfo userInfo = new UserInfo();

? ? ? ? userInfo.points=100;

? ? ? ? return userInfo;

? ? }

? ? public class UserInfo{

? ? ? ? public int id;

? ? ? ? public int points;

? ? }

運行結果

=====>: ------------test06-----------

? ? ? ? ----------線程調度---------

=====>: 顯示用戶積分:100

在io線程中根據id請求用戶信息,在主線程中將用戶積分顯示到界面

Schedulers.newThread(): 總是啟用新線程,并在新線程執行操作,適用于復雜計算。

Schedulers.io(): I/O 操作(讀寫文件、讀寫數據庫、網絡信息交互等)

AndroidSchedulers.mainThread(),它指定的操作將在 Android 主線程運行

subscribeOn(): 指定 subscribe() 所發生的線程,即 Observable.OnSubscribe 被激活時所處的線程。或者叫做事件產生的線程。

observeOn(): 指定 Subscriber 所運行在的線程。或者叫做事件消費的線程

6、變換

舉一個例子:通過用戶id,從數據庫中請求用戶名稱,只需要名稱就行,id是int類型,用戶名稱是string類型

public void test07(){

? ? ? ? Log.e(tag, "------------test07-----------" +

? ? ? ? ? ? ? ? "\n----------變換01---------");

? ? ? ? //從數據庫中根據id獲取用戶名稱

? ? ? ? Observable.just(111)

? ? ? ? ? ? ? ? .map(new Func1() {

? ? ? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? ? ? public String call(Integer id) {

? ? ? ? ? ? ? ? ? ? ? ? return getNameFromDb(id);

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? })

? ? ? ? ? ? ? ? .subscribe(new Action1() {

? ? ? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? ? ? public void call(String s) {

? ? ? ? ? ? ? ? ? ? ? ? Log.e(tag,s);

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? });

? ? }

? ? //模擬從數據獲取信息

? ? private String getNameFromDb(int id){

? ? ? ? return "username";

? ? }

? ? public class UserInfo{

? ? ? ? public int id;

? ? ? ? public String name;

? ? ? ? public int points;

? ? }

運行結果

=====>: ------------test07-----------

? ? ? ? ----------變換01---------

=====>: username

這里的map有轉換的作用,這里是吧Observable轉換成了Observable,事件只能是一對一的轉換,把發射id的事件,轉換成了發射username的事件

flatmap轉換,舉一個例子:根據id從數據庫中獲取指定用戶的愛好,并打印出來

public void test08(){

? ? ? ? Log.e(tag, "------------test08-----------" +

? ? ? ? ? ? ? ? "\n----------變換02---------");

? ? ? ? Observable.just(111)

? ? ? ? ? ? ? ? .flatMap(new Func1>() {

? ? ? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? ? ? public Observable call(Integer id) {

? ? ? ? ? ? ? ? ? ? ? ? return Observable.from(getHobbies(id));

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? })

? ? ? ? ? ? ? ? .subscribe(new Action1() {

? ? ? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? ? ? public void call(String s) {

? ? ? ? ? ? ? ? ? ? ? ? Log.e(tag,s);

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? });

? ? }

? ? //模擬從數據獲取信息

? ? private String[] getHobbies(int id){

? ? ? ? return new String[]{"singing","running","shopping"};

? ? }

? ? public class UserInfo{

? ? ? ? public int id;

? ? ? ? public String name;

? ? ? ? public int points;

? ? ? ? public String[] hobbies;

? ? }

運行結果

=====>: ------------test08-----------

? ? ? ? ----------變換02---------

=====>: singing

=====>: running

=====>: shopping

這里將Observable轉換成了?Observable.from(getHobbies(id)),將發射id的事件,轉換成了多個發射愛好的事件(愛好有多個),事件是一對多

7、反注冊

rxJava是基于觀察者模式的,我們知道觀察者模式中有注冊和反注冊,反注冊就是為了釋放資源,防止內存泄露,rxjava中也是,我們也需要及時反注冊并釋放資源,

? ? private Subscription subscription;

? ? public void test09(){

? ? ? ? Log.e(tag, "------------test09-----------" +

? ? ? ? ? ? ? ? "\n----------反注冊---------");

? ? ? ? subscription = Observable.create(new Observable.OnSubscribe() {

? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? public void call(Subscriber subscriber) {

? ? ? ? ? ? ? ? ? ? SystemClock.sleep(5000);\\暫停5秒鐘

? ? ? ? ? ? ? ? ? ? subscriber.onNext("hahaha");

? ? ? ? ? ? ? ? ? ? subscriber.onCompleted();\\標志事件發送完畢,just和from會自動調用onCompleted

? ? ? ? ? ? ? ? }

? ? ? ? ? ? })

? ? ? ? ? ? .subscribeOn(Schedulers.newThread())

? ? ? ? ? ? .observeOn(AndroidSchedulers.mainThread())

? ? ? ? ? ? .subscribe(new Action1() {

? ? ? ? ? ? @Override

? ? ? ? ? ? public void call(String s) {

? ? ? ? ? ? ? ? Log.e(tag, s);

? ? ? ? ? ? }

? ? ? ? });

? ? }

? ? @Override

? ? protected void onDestroy() {

? ? ? ? super.onDestroy();

? ? ? ? Log.e(tag,"是否已經反注冊:"+subscription.isUnsubscribed()+"");

? ? ? ? //先判斷是否已經反注冊

? ? ? ? if(!subscription.isUnsubscribed()){

? ? ? ? ? ? Log.e(tag,"進行反注冊");

? ? ? ? ? ? subscription.unsubscribe();

? ? ? ? ? ? Log.e(tag,"是否已經反注冊:"+subscription.isUnsubscribed()+"");

? ? ? ? }

? ? }

Subscription是注冊關系,Observable調用subscribe方法時,會形成一個注冊關系,Subscription的isUnsubscribed()方法來判斷是否已經反注冊,unsubscribe()方法來進行反注冊。一般情況下,當事件發送完成后,觀察者會自動反注冊,不用我們調用Subscription的unsubscribe()方法進行反注冊,但是當有耗時操作時,我們就有必要進行反注冊,上面代碼的運行結果如下:

運行結果

在事件還沒有發送完畢時(5秒之內),我們關閉了activity:

=====>: ------------test09-----------

? ? ? ? ----------反注冊---------

=====>: 是否已經反注冊:false

=====>: 進行反注冊

=====>: 是否已經反注冊:true

事件已經發送完(5秒之后),我們關閉activity:

=====>: ------------test09-----------

? ? ? ? ----------反注冊---------

=====>: hahaha

=====>: 是否已經反注冊:true

8、操作符使用

rxJava有著豐富的操作符,來對數據進行流式的操作處理,上面講到的map和flatmap就是rxJava的操作符,由于操作符太多,只示范常用的幾個:

public void test10(){

? ? Log.e(tag, "------------test10-----------" +

? ? ? ? ? ? "\n----------操作符---------");

? String[] strs={"aa","bb","bb","cc","dd","ee"};

? ? Observable observable = Observable.from(strs);

? ? //filter(Func1)方法來過濾我們觀測序列中不想要的值

? ? //take(count)方法來限制獲取多少個數據

? ? Log.e(tag,"---------filter & take----------");

? ? observable

? ? ? ? ? ? .filter(new Func1() {

? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? public Boolean call(String s) {

? ? ? ? ? ? ? ? ? ? //把已b結尾的數據去掉

? ? ? ? ? ? ? ? ? ? return !s.endsWith("b");

? ? ? ? ? ? ? ? }

? ? ? ? ? ? })

? ? ? ? ? ? .take(3)//取3個數據

? ? ? ? ? ? .subscribe(new Action1() {

? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? public void call(String s) {

? ? ? ? ? ? ? ? ? ? Log.e(tag,s);

? ? ? ? ? ? ? ? }

? ? ? ? });

? ? Log.e(tag,"---------skip & first----------");

? ? observable

? ? ? ? ? ? .skip(3)

? ? ? ? ? ? .first()

? ? ? ? ? ? .subscribe(new Action1() {

? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? public void call(String s) {

? ? ? ? ? ? ? ? ? ? Log.e(tag,s);

? ? ? ? ? ? ? ? }

? ? ? ? ? ? });

}

運行結果

=====>: ------------test10-----------

? ? ? ? ----------操作符---------

=====>: ---------filter & take----------

=====>: aa

=====>: cc

=====>: dd

=====>: ---------skip & first----------

=====>: cc

類似的這種簡單的操作符還有:

last() 取最后一個

distinct() 去除重復的

skipLast() 去除最后一個

takeLast(count) 取最后count個

limit(count) 限制個數

doOnNext(Action1) 允許我們在每次輸出一個元素之前做一些額外的事情,比如保存起來。

還有好多,這只是簡單的介紹一下,在RxJava操作符專題中有詳解

9、RxLifecycle

我們上面提到了反注冊來防止內存泄露,但是反注冊需要我們自己動手寫,而使用Rxlifecycle就可以幫助我們將反注冊綁定到activity或者fragment的生命周期中,在他們的生命周期中自動去解綁。

使用方法

添加依賴,有最新的依賴,但是下面的比較穩定編譯也能通過

compile 'com.trello:rxlifecycle:0.3.1'

compile 'com.trello:rxlifecycle-components:0.3.1'

Activity/Fragment需繼承RxAppCompatActivity/RxFragment,目前支持的有RxAppCompatActivity、RxFragment、RxDialogFragment、RxFragmentActivity

綁定生命周期的時候可調用的方法:

bindToLifecycle()

bindUntilEvent()

例子

public class MainActivity extends RxAppCompatActivity {

? ? private static final String TAG = "=====>";

? ? @Override

? ? protected void onCreate(Bundle savedInstanceState) {

? ? ? ? super.onCreate(savedInstanceState);

? ? ? ? Log.e(TAG, "onCreate()");

? ? ? ? setContentView(R.layout.activity_main);

? ? ? ? Observable.interval(1, TimeUnit.SECONDS)

? ? ? ? ? ? ? ? .doOnUnsubscribe(new Action0() {

? ? ? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? ? ? public void call() {

? ? ? ? ? ? ? ? ? ? ? ? Log.e(TAG, "Unsubscribing subscription from onCreate()");

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? })

? ? ? ? ? ? ? ? .compose(this.bindUntilEvent(ActivityEvent.PAUSE))

? ? ? ? ? ? ? ? .subscribe(new Action1() {

? ? ? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? ? ? public void call(Long num) {

? ? ? ? ? ? ? ? ? ? ? ? Log.e(TAG, "Started in onCreate(), running until onPause(): " + num);

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? });

? ? }

? ? @Override

? ? protected void onStart() {

? ? ? ? super.onStart();

? ? ? ? Log.e(TAG, "onStart()");

? ? ? ? // Using automatic unsubscription, this should determine that the correct time to

? ? ? ? // unsubscribe is onStop (the opposite of onStart).

? ? ? ? Observable.interval(1, TimeUnit.SECONDS)

? ? ? ? ? ? ? ? .doOnUnsubscribe(new Action0() {

? ? ? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? ? ? public void call() {

? ? ? ? ? ? ? ? ? ? ? ? Log.e(TAG, "Unsubscribing subscription from onStart()");

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? })

? ? ? ? ? ? ? ? .compose(this.bindToLifecycle())

? ? ? ? ? ? ? ? .subscribe(new Action1() {

? ? ? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? ? ? public void call(Long num) {

? ? ? ? ? ? ? ? ? ? ? ? Log.e(TAG, "Started in onStart(), running until in onStop(): " + num);

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? });

? ? }

? ? @Override

? ? protected void onResume() {

? ? ? ? super.onResume();

? ? ? ? Log.e(TAG, "onResume()");

? ? ? ? // `this.` is necessary if you're compiling on JDK7 or below.

? ? ? ? //

? ? ? ? // If you're using JDK8+, then you can safely remove it.

? ? ? ? Observable.interval(1, TimeUnit.SECONDS)

? ? ? ? ? ? ? ? .doOnUnsubscribe(new Action0() {

? ? ? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? ? ? public void call() {

? ? ? ? ? ? ? ? ? ? ? ? Log.e(TAG, "Unsubscribing subscription from onResume()");

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? })

? ? ? ? ? ? ? ? .compose(this.bindUntilEvent(ActivityEvent.DESTROY))

? ? ? ? ? ? ? ? .subscribe(new Action1() {

? ? ? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? ? ? public void call(Long num) {

? ? ? ? ? ? ? ? ? ? ? ? Log.e(TAG, "Started in onResume(), running until in onDestroy(): " + num);

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? });

? ? }

? ? @Override

? ? protected void onPause() {

? ? ? ? super.onPause();

? ? ? ? Log.e(TAG, "onPause()");

? ? }

? ? @Override

? ? protected void onStop() {

? ? ? ? super.onStop();

? ? ? ? Log.e(TAG, "onStop()");

? ? }

? ? @Override

? ? protected void onDestroy() {

? ? ? ? super.onDestroy();

? ? ? ? Log.e(TAG, "onDestroy()");

? ? }

}

打開activity,兩秒后關閉,這樣每一個Observable發送兩個事件

運行結果

=====>: onCreate()

=====>: onStart()

=====>: onResume()

=====>: Started in onCreate(), running until onPause(): 0

=====>: Started in onStart(), running until in onStop(): 0

=====>: Started in onResume(), running until in onDestroy(): 0

=====>: Started in onCreate(), running until onPause(): 1

=====>: Started in onStart(), running until in onStop(): 1

=====>: Started in onResume(), running until in onDestroy(): 1

=====>: Unsubscribing subscription from onCreate()

=====>: onPause()

=====>: Unsubscribing subscription from onStart()

=====>: onStop()

=====>: Unsubscribing subscription from onResume()

關閉activity后,可以看出每一個Observable對應的注冊者在相應的生命周期函數中反注冊。?bindUntilEvent()方法需要傳入要綁定的生命周期。使用ActivityEvent類,其中的CREATE、START、 RESUME、PAUSE、STOP、 DESTROY分別對應生命周期內的方法。使用bindUntilEvent指定在哪個生命周期方法調用時取消訂閱

bindToLifecycle()方法完成Observable發布的事件和當前的組件綁定,實現生命周期同步。從而實現當前組件生命周期結束時,自動取消對Observable訂閱。

10、RxBinding

RxBinding是Rx中處理控件異步調用的方式, 也是由Square公司開發, Jake負責編寫. 通過綁定組件, 異步獲取事件, 并進行處理。

使用

關聯

compile 'com.jakewharton.rxbinding:rxbinding:0.4.0'

compile 'com.jakewharton.rxbinding:rxbinding-support-v4:0.4.0'

實例


? ? xmlns:tools="http://schemas.android.com/tools"

? ? android:layout_width="match_parent"

? ? android:layout_height="match_parent"

? ? android:paddingBottom="@dimen/activity_vertical_margin"

? ? android:paddingLeft="@dimen/activity_horizontal_margin"

? ? android:paddingRight="@dimen/activity_horizontal_margin"

? ? android:paddingTop="@dimen/activity_vertical_margin"

? ? android:orientation="vertical"

? ? tools:context="cn.domob.android.rxjava_android.MainActivity">


? ? ? ? android:id="@+id/tv_main"

? ? ? ? android:layout_width="match_parent"

? ? ? ? android:layout_height="wrap_content"

? ? ? ? android:text="Hello World!" />


? ? ? ? android:id="@+id/bt_main_01"

? ? ? ? android:layout_width="match_parent"

? ? ? ? android:layout_height="wrap_content"

? ? ? ? android:text="改變字體顏色"/>


? ? ? ? android:id="@+id/bt_main_02"

? ? ? ? android:layout_width="match_parent"

? ? ? ? android:layout_height="wrap_content"

? ? ? ? android:text="長按彈toast"/>


? ? ? ? android:id="@+id/et_main"

? ? ? ? android:layout_width="match_parent"

? ? ? ? android:layout_height="wrap_content"

? ? ? ? android:hint="搜索"/>


? ? ? ? android:id="@+id/lv_main"

? ? ? ? android:layout_width="match_parent"

? ? ? ? android:layout_height="match_parent"/>

public class MainActivity extends RxAppCompatActivity {

? ? private static final String TAG = "=====>";

? ? @InjectView(R.id.tv_main)

? ? TextView tv;

? ? @InjectView(R.id.bt_main_01)

? ? Button bt01;

? ? @InjectView(R.id.bt_main_02)

? ? Button bt02;

? ? @InjectView(R.id.et_main)

? ? EditText et;

? ? @InjectView(R.id.lv_main)

? ? ListView lv;

? ? @Override

? ? protected void onCreate(Bundle savedInstanceState) {

? ? ? ? super.onCreate(savedInstanceState);

? ? ? ? setContentView(R.layout.activity_main);

? ? ? ? ButterKnife.inject(this);

? ? ? ? //單機事件

? ? ? ? RxView.clicks(bt01).subscribe(new Action1() {

? ? ? ? ? ? @Override

? ? ? ? ? ? public void call(Void aVoid) {

? ? ? ? ? ? ? ? tv.setTextColor(Color.parseColor("#ff0000"));

? ? ? ? ? ? }

? ? ? ? });

? ? ? ? //長按事件

? ? ? ? RxView.longClicks(bt02).subscribe(new Action1() {

? ? ? ? ? ? @Override

? ? ? ? ? ? public void call(Void aVoid) {

? ? ? ? ? ? ? ? Toast.makeText(MainActivity.this, "hahha", Toast.LENGTH_SHORT).show();? ?

? ? ? ? ? ? }

? ? ? ? });

? ? ? ? //防止連續點擊

? ? ? ? RxView.clicks(bt02).throttleFirst(5, TimeUnit.SECONDS).subscribe(new Action1() {

? ? ? ? ? ? @Override

? ? ? ? ? ? public void call(Void aVoid) {

? ? ? ? ? ? ? ? Toast.makeText(MainActivity.this, "防止多次連續點擊", Toast.LENGTH_SHORT).show();

? ? ? ? ? ? }

? ? ? ? });

? ? ? ? //完成關鍵詞聯想功能,debounce()在一定的時間內沒有操作就會發送事件,顯示關鍵詞

? ? ? ? final ArrayAdapter adapter = new ArrayAdapter<>(this, android.R.layout.simple_expandable_list_item_1);

? ? ? ? lv.setAdapter(adapter);

? ? ? ? RxTextView.textChanges(et)

? ? ? ? ? ? ? ? .debounce(600,TimeUnit.MILLISECONDS)

? ? ? ? ? ? ? ? .map(new Func1() {

? ? ? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? ? ? public String call(CharSequence charSequence) {

? ? ? ? ? ? ? ? ? ? ? ? return charSequence.toString();

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? })

? ? ? ? ? ? ? ? .map(new Func1>() {

? ? ? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? ? ? public List call(String key) {

? ? ? ? ? ? ? ? ? ? ? ? ArrayList arrayList = new ArrayList<>();

? ? ? ? ? ? ? ? ? ? ? ? if(!TextUtils.isEmpty(key)){

? ? ? ? ? ? ? ? ? ? ? ? ? ? for (int i = 0; i < getdata().size(); i++) {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if(getdata().get(i).contains(key))

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? arrayList.add(getdata().get(i));

? ? ? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ? ? return arrayList;

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? })

? ? ? ? ? ? ? ? .observeOn(AndroidSchedulers.mainThread())

? ? ? ? ? ? ? ? .subscribe(new Action1>() {

? ? ? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? ? ? public void call(List strings) {

? ? ? ? ? ? ? ? ? ? ? ? adapter.clear();

? ? ? ? ? ? ? ? ? ? ? ? adapter.addAll(strings);

? ? ? ? ? ? ? ? ? ? ? ? adapter.notifyDataSetChanged();

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? });

? ? ? ? RxAdapterView.itemClicks(lv).subscribe(new Action1() {

? ? ? ? ? ? @Override

? ? ? ? ? ? public void call(Integer integer) {

? ? ? ? ? ? ? ? et.setText(adapter.getItem(integer));

? ? ? ? ? ? }

? ? ? ? });

? ? }

? ? public List getdata(){

? ? ? ? return Arrays.asList("abc","abddfds","123","124567","1278934","adfghjl","!@#45d","響應式編程");

? ? }

}

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容