RxJava1的使用介紹

1.RxJava是什麼?
2.觀察者模式?
3.RxJava中的觀察者模式?
4.創建觀察者。
5.創建被觀察者。
6.Subscribe 訂閱。
7.變換操作符。
8.線程調度。

1.RxJava是什麼?
  RxJava是一個可異步處理事件的框架。
  在Android中異步一詞很重要。Android規定在處理耗時操作時,需要開啓一個子線程處理任務,這樣會出現子線程和主線程通信的問題。
  Android提供了Handler,AsynTask,HandlerThread等方式處理異步問題。
  當業務繁多的時候,使用這些方式會變得代碼臃腫,邏輯不清晰。這個時候就用到了Rxjava。
  RxJava是一種基於可擴展的觀察者模式實現的。

2.觀察者模式?
  是一種對象間存在的一對一或一對多的關係。這種關係是依賴性的。當一個對象的狀態發生變化時,所有依賴它的對象將收到通知。
  例子:用戶關注了一個公衆號,當公衆號有新的文章發表時,用戶會收到提醒。

  在這個模式中存在四個角色:
  2.1 抽象被觀察者:抽象出被觀察者所具有的行爲。比如可以添加用戶,刪除用戶,通知用戶等。
  2.2 抽象觀察者:抽象出觀察者所具有的行爲。比如收到通知等。
  2.3 具體被觀察者:具有抽象被觀察者行爲的實物。比如網站。
  2.4 具體觀察者:具有抽象觀察者行爲的實物。比如人。

在代碼中實現

抽象觀察者:
public interface InterfaceUserObserver {
    void update(String message);
  }
 抽象被觀察者:
public interface InterfaceWebsiteObserverable {
     void register(User user);//接受用於關注
     void remove(User user);//刪除用戶
     void notifyUser();//通知用戶
  }
具體觀察者:
 public class User implements InterfaceUserObserver {

    private String name;

    public User(String name){
        this.name = name;
    }

    @Override
    public void update(String message) {
      System.out.println(name+"收到了一條消息:"+message);
    }
   }
  具體被觀察者:
   
public class Website implements InterfaceWebsiteObserverable{
    private List<User>  users;
    private String message;

    public Website(){
        users = new ArrayList<>();
    }

    @Override
    public void register(User user) {
       users.add(user);
    }

    @Override
    public void remove(User user) {
        users.remove(user);
    }

    @Override
    public void notifyUser() {
      for(User user:users){
          user.update(message);
      }
    }

    public void setMessage(String msg){
        message = msg;
        notifyUser();
    }
}
Website website = new Website();
        website.register(new User("小A"));
        website.register(new User("小B"));
        website.register(new User("小C"));
        website.register(new User("小D"));
        website.setMessage("今日看點:周杰倫的新歌發佈啦。");


打印:
小A收到了一條消息:今日看點:周杰倫的新歌發佈啦。
小B收到了一條消息:今日看點:周杰倫的新歌發佈啦。
小C收到了一條消息:今日看點:周杰倫的新歌發佈啦。
小D收到了一條消息:今日看點:周杰倫的新歌發佈啦。


3.RxJava中的觀察者模式
存在四個角色:
3.1 觀察者 Observer/Subscriber
3.2 被觀察者 Observable
3.3 訂閱  subscribe
3.4 事件  event
觀察者Observer 和 被觀察者Observable的聯繫是通過 subscribe訂閱的。在有需要的時候被觀察者會發送事件通知觀察者。

4.創建觀察者
觀察者Observer決定了事件觸發的時候將有怎樣的行爲。
Observer observer = new Observer<String>(){
            @Override
            public void onCompleted() { }

            @Override
            public void onError(Throwable e) { }

            @Override
            public void onNext(String s) { }
        };
onCompleted():當被觀察者調用onCompleted時觸發。
onError():當被觀察者調用onError時觸發。
onNext():當被觀察者調用onNext時觸發。
另外一種方式:

Subscriber  subscriber = new Subscriber<String>(){

            @Override
            public void onStart() {
                super.onStart();
            }

            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(String s) {

            }
        };

        subscriber.unsubscribe();
        subscriber.isUnsubscribed();
Subscriber 相對 Observer來說會多出三個方法:
onStart():在事件開始發送前調用。這個方法只會在subscribe發生的線程執行。
isUnsubscribed():判斷是否訂閱被取消。
unsubscribe():取消訂閱。


5.創建被觀察者
被觀察者Observable決定什麼時候觸發事件以及觸發怎樣的事件。

5.1通過create創建被觀察者
Observable observable = Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {
                  subscriber.onNext("事件A");
                  subscriber.onNext("事件B");
                  subscriber.onCompleted();
            }
        });

observable.subscribe(observer);

打印:
onNext:事件A
onNext:事件B
onCompleted
5.2通過just創建被觀察者
Observable observable1 = Observable.just("hello");自動調用onNext()和onCompleted()
observable1.subscribe(observer);

打印:
onNext:hello
onCompleted
5.3通過from創建被觀察者
from()方法將傳入的數組或Iterable拆分成具體對象後,自動調用OnNext方法一次發送。
Observable observable2 = Observable.from(new String[]{
           "a","b","c","d","e"
        });

List<String> list = new ArrayList<>();
        list.add("aa");
        list.add("bb");
        list.add("cc");
        list.add("dd");
        list.add("ee");
Observable observable3 = Observable.from(list);

observable3.subscribe(observer);

打印:
onNext:bb
onNext:cc
onNext:dd
onNext:ee
onCompleted
5.4 通過defer()創建被觀察者
當觀察者訂閱時才創建Observable,並且對應每個觀察者都會創建一個新的Observable。

Observable observable4 = Observable.defer(new Func0<Observable<String>>() {
            @Override
            public Observable<String> call() {
                Observable childObservable = Observable.create(new Observable.OnSubscribe<String>() {
                    @Override
                    public void call(Subscriber<? super String> subscriber) {
                        subscriber.onNext("開始訂閱事件了");
                    }
                });
                return childObservable;
            }
        });

        observable4.subscribe(new Action1<String>() {
            @Override
            public void call(String s) {
               System.out.println("觀察者1訂閱 "+s);
            }
        });

        observable4.subscribe(new Action1<String>() {
            @Override
            public void call(String s) {
                System.out.println("觀察者2訂閱 "+s);
            }
        });
使用defer()方法,每當產生新的訂閱事件時都會生成一個新的Observable對象。


5.5 interval()
創建一個按固定時間間隔發送整數序列的Observable,可作爲輪詢器使用。
Observable observable5 = Observable.interval(1,TimeUnit.SECONDS);
        observable5.subscribe(new Action1<Long>() {
            @Override
            public void call(Long aLong) {
                System.out.println("時間間隔:"+aLong);
            }
        });
5.6 timer()
延遲一定的時間後才發送事件。
Observable observable = Observable.timer(2000,TimeUnit.MILLISECONDS);
        Subscriber subscriber = new Subscriber<Long>() {

            @Override
            public void onCompleted() {
              System.out.println("onCompleted");
            }

            @Override
            public void onError(Throwable e) {
                System.out.println("onError");
            }

            @Override
            public void onNext(Long aLong) {
                System.out.println("onNext  收到消息啦");
            }
        };
6.Subscribe 訂閱
一般會使用Observable.subscribe()方法將被觀察者和觀察者聯繫起來。

6.1 不完整定義回調 Action接口,常用的有Action0和Action1
Action0:它只有一個方法call(),這個方法無參數無返回值;
Action1:它只有一個方法call(T param),這個方法有一個參數無返回值;

ActionX:表示這個call()這個方法有X個參數。
Action0 onCompleteAction = new Action0() {
            @Override
            public void call() {
                 System.out.println("onCompleteAction");
            }
        };

        Action1 onNextAction = new Action1<String>(){
            @Override
            public void call(String s) {
               System.out.println("onNext:"+s);
            }
        };

        Action1 onErrorAction = new Action1<Throwable>(){
            @Override
            public void call(Throwable throwable) {
                System.out.println("onErrorAction");
            }
        };

//只處理onNext事件
 observable.subscribe(onNextAction);
//只處理onNext和onError事件
 observable.subscribe(onNextAction,onErrorAction);
//只處理onNext,onError和onCompleted事件
 observable.subscribe(onNextAction,onErrorAction,onCompleteAction);
7.變換操作符
變換操作符的作用是將事件序列中的對象或整個系列進行加工處理,轉換成不同的事件。

7.1 map
map操作符通過制定一個Func1對象,將原Observable對象轉換爲另一個Observable對象併發送。


List<Course> courses = new ArrayList<>();
        courses.add(new Course("西遊記"));
        courses.add(new Course("紅樓夢"));
        courses.add(new Course("水滸傳"));
        courses.add(new Course("三國演義"));

        Observable.from(courses)
                .map(new Func1<Course,String>(){
                    @Override
                    public String call(Course course) {
                        return course.getCourseName();
                    }
                }).subscribe(new Action1<String>() {
            @Override
            public void call(String s) {
                System.out.println("你要讀:"+s);
            }
        });

打印:
你要讀:西遊記
你要讀:紅樓夢
你要讀:水滸傳
你要讀:三國演義List<Course> courses = new ArrayList<>();
        courses.add(new Course("西遊記"));
        courses.add(new Course("紅樓夢"));
        courses.add(new Course("水滸傳"));
        courses.add(new Course("三國演義"));

        Observable.from(courses)
                .map(new Func1<Course,String>(){
                    @Override
                    public String call(Course course) {
                        return course.getCourseName();
                    }
                }).subscribe(new Action1<String>() {
            @Override
            public void call(String s) {
                System.out.println("你要讀:"+s);
            }
        });

打印:
你要讀:西遊記
你要讀:紅樓夢
你要讀:水滸傳
你要讀:三國演義
傳入一個course對象,返回的是String類型的數據。

FuncX和ActionX是類似的,不同的是FuncX是有返回值的。
例如:Func1和Action1,Func1有一個參數,有返回值;
Action1有一個參數,沒有返回值。


7.2 flatMap
flatMap也是可以做變換的。不同於map的是,flatMap返回的是一個Observable類型。
List<Student> students = new ArrayList<>();
        Student studentA = new Student("小明",new ArrayList<Course>());
        studentA.getCourses().add(new Course("西遊記"));
        studentA.getCourses().add(new Course("紅樓夢"));
        studentA.getCourses().add(new Course("水滸傳"));
        studentA.getCourses().add(new Course("三國演義"));

        Student studentB = new Student("小王",new ArrayList<Course>());
        studentB.getCourses().add(new Course("語文"));
        studentB.getCourses().add(new Course("數學"));
        studentB.getCourses().add(new Course("英語"));

        Student studentC = new Student("小強",new ArrayList<Course>());
        studentC.getCourses().add(new Course("C語言"));
        studentC.getCourses().add(new Course("Java"));
        studentC.getCourses().add(new Course("C++"));

        students.add(studentA);
        students.add(studentB);
        students.add(studentC);

       Observable.from(students)
               .flatMap(new Func1<Student, Observable<Course>>() {
                   @Override
                   public Observable<Course> call(Student student) {
                       return Observable.from(student.getCourses());
                   }
               }).subscribe(new Action1<Course>() {
           @Override
           public void call(Course course) {
               System.out.println(course.getCourseName());
           }
       });
7.3 變換的原理
RxJava 提供很多中變換,但本質上都是對事件序列的處理再發送。這個過程都離不開lift()。

public final <R> Observable<R> map(Func1<? super T, ? extends R> func) {
        return lift(new OperatorMap<T, R>(func));
}

public final <R> Observable<R> lift(final Operator<? extends R, ? super T> operator) {
        return new Observable<R>(new OnSubscribeLift<T, R>(onSubscribe, operator));
}
在調用的lift方法時,返回一個新的Observable對象。而這個新的Observable對象需要的參數是一個新的OnSubscribe。

當有lift()時,
(1)lift()會創建一個新的Observable,對應的也會有一個新的OnSubscribe。
(2)當調用lift()後的Observable.subscribe()的時候,使用的是lift()創建的新的Observable,於是它所觸發的onSubscribe.call(subscriber),是新Observable中的新OnSubscribe。
(3)這個新OnSubscribe的call()方法中的OnSubscribe,就是原始Observable的onSubscribe,在這個call()方法裏,新OnSubscribe利用
operator.call(subscriber)生成了一個新的Subscriber,然後利用這個新Subscriber向原始Observable進行訂閱。




總結:
新創建的一個Subscriber與原始的Observable的Subscriber關聯起來。當產生事件訂閱時,新的Observable訂閱了事件,然後通知原始Observable開始發送事件,
原始Observable將事件發送給新的Subscriber,經過處理後發送給原始的Observable的Subscriber。

當多個lift()時:

8.線程調度
RxJava的線程調度使用的時Scheduler類。
Scheduler的Api
Schedulers.immediate(): 直接在當前線程運行。
Schedulers.newThread():啓用新線程,並在新線程執行操作。
Schedulers.io():啓動I/O操作。
Schedulers.computation(): 計算所使用的 Scheduler。
Android專用的AndroidSchedulers.mainThread():它執行的操作將在Android主線程運行。


例子:
 
Observable.from(students)
               .flatMap(new Func1<Student, Observable<Course>>() {
                   @Override
                   public Observable<Course> call(Student student) {
                       return Observable.from(student.getCourses());
                   }
               })
               .subscribeOn(Schedulers.io())
               .observeOn(AndroidSchedulers.mainThread())
               .subscribe(new Action1<Course>() {
           @Override
           public void call(Course course) {
               System.out.println(course.getCourseName());
           }
       });
subscriberOn():指定Observable(被觀察者)所在的線程,叫做事件產生線程;
observeOn():指定Observer(觀察者)所運行在的線程,叫做事件消費線程。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章