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(觀察者)所運行在的線程,叫做事件消費線程。