RxJava => java響應式編程庫html
入門教程:http://blog.danlew.net/2014/09/15/grokking-rxjava-part-1/ 教程很不錯,重點是評論java
基本元素:Observable、Observer編程
基本概念:RxJava基於觀察者模式的思路設計響應式編程,Observable能夠看作是被觀察對象,能夠發出任意事件,經過OnSubscribe接口調用
Observer中的方法,以達到通知觀察者的目的。json
基本實現:網絡
經過Rxjava實現輸出3個字符串:app
定義一個Observable對象:
Observable o1 = Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
subscriber.onNext("A");
subscriber.onNext("A");
subscriber.onNext("A");
subscriber.onCompleted();
}
});
定義一個Observer對象
Observer observer = new Observer() {
@Override
public void onCompleted() {ide
}測試
@Override
public void onError(Throwable e) {this
}.net
@Override
public void onNext(Object o) {
Toast.makeText(SplashActivity.this,o.toString(),Toast.LENGTH_SHORT).show();
}
}
將Observable和Observer關聯
o1.subscribe(observer);
完成!
Observable負責接收三個字符串,經過一個監聽該Observable的Observer對象來輸出這3個字符串,與這個例子相似的模型:
class A{
private String message = "Hello World";
private InterfaceA interfaceA;
public Interface InterfaceA{
void call(String message);
}
public void doMessage(){
if (interfaceA != null) {
interfaceA.call(messgae);
} else {
System.out.println(message);
}
}
public void setInterfaceA(InterfaceA interfaceA){
this.interfaceA = interfaceA;
}
}
class B {
InterfaceA ia = new InterfaceA(){
public void call(String message){
Log.d("Turman",message);
}
}
A a = new A();
a.setInterfaceA(ia);
a.doMessage();
}
幾種建立Observable的封裝:
1.如上面的例子能夠經過just建立一個處理3個字符創的Observable:Observable.just("A","A","A")
2.經過from:Observable.from(new String[]{"A","A","A"})
對Observer的封裝:Subscriber對Observer進行了分裝,增長了onStart方法能夠在onNext被調用前作一些必要的處理,另外,經過
經過Subscriber能夠unsubscribe,避免內存泄露。
變換lift:
實現輸出一個字符串:
Observable.just("Hello World")
.subscribe(new Subscriber() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(String s) {
Toast.makeText(SplashActivity.this,s,Toast.LENGTH_SHORT).show();
}
});
實現輸出字符串的長度:
Observable.just("Hello World".length())
.subscribe(new Subscriber() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(int length) {
Toast.makeText(SplashActivity.this,length+"",Toast.LENGTH_SHORT).show();
}
});
還能夠經過lift實現:
Observable.just("Hello World").lift(new Observable.Operator<Integer, String>() {
@Override
public Subscriber<? super String> call(final Subscriber<? super Integer> subscriber) {
return new Subscriber<String>() {
@Override
public void onCompleted() {
subscriber.onCompleted();
}
@Override
public void onError(Throwable e) {
subscriber.onError(e);
}
@Override
public void onNext(String s) {
int value = s.length();
subscriber.onNext(value);
}
};
}
}).subscribe(new Subscriber() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(int length) {
Toast.makeText(SplashActivity.this,length+"",Toast.LENGTH_SHORT).show();
}
});
理解lift很簡單,Observable.Operator接口中經過在新建的Observable<Integer>中調用初始Observable<String>的方法,並將
Observable<Integer>返回,相似代理。經過lift能夠實現不少自定義的Observable變換,如:
Observable.from(new Integer[]{1,2,3,4,5,6,7,8}).lift(new Observable.Operator<Integer, Integer>() {
@Override
public Subscriber<? super Integer> call(final Subscriber<? super Integer> subscriber) {
return new Subscriber<Integer>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(Integer integer) {
if (integer % 2 == 1) { //只輸出奇數
subscriber.onNext(integer);
}
}
};
}
}).subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
Toast.makeText(SplashActivity.this, integer+"",Toast.LENGTH_SHORT).show();
}
});
lift的幾個封裝:
Map ->
Observable.just(1,2,3,4).map(new Func1<Integer, Integer>() {
@Override
public Integer call(Integer integer) {
return 1 * 1000;
}
}).subscribe(new Subscriber<Integer>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(Integer integer) {
Toast.makeText(SplashActivity.this,integer.toString(),Toast.LENGTH_SHORT).show();
}
});
這是一個簡單的序列變換,將輸出的全部數字乘以100,可是輸入的數據類型沒有變,若是要將輸出的內容進行變換則須要flatMap
flatMap ->
Observable.from(new String[]{"A","B","C"})
.flatMap(new Func1<String, Observable<Integer>>() {
@Override
public Observable<Integer> call(String s) {
return Observable.just(s.hashCode());
}
}).subscribe(new Subscriber<Integer>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(Integer integer) {
Toast.makeText(SplashActivity.this, integer.toString(),Toast.LENGTH_SHORT).show();
}
});
轉換成輸出3個字符的哈希碼
filter ->
如下例子過濾奇數,輸出偶數:
Observable.from(new Integer[]{20,21,22,23,24}).filter(new Func1<Integer, Boolean>() {
@Override
public Boolean call(Integer integer) {
return integer % 2 == 0;
}
}).subscribe(new Subscriber<Integer>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(Integer integer) {
Toast.makeText(SplashActivity.this, integer.toString(),Toast.LENGTH_SHORT).show();
}
});
關於FuncX和ActionX接口的說明
FuncX表示的是接口方法有返回值得接口,ActionX表示的是接口方法沒有返回值的接口,
其中,X-表明接口參數的數量,filter中的例子能夠寫成這樣:
Observable.from(new Integer[]{20,21,22,23,24}).filter(new Func1<Integer, Boolean>() {
@Override
public Boolean call(Integer integer) {
return integer % 2 == 0;
}
}).subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
Toast.makeText(SplashActivity.this, integer.toString(),Toast.LENGTH_SHORT).show();
}
});
Observer(Subscriber)幾個方法的調用,onNext業務處理,onError在處理異常時調用,onCompleted在處理結束時調用,
因此onNext會調用屢次而onError和onCmpleted值會調用一次。同時,
onError特性:onError() is called if an Exception is thrown at any time. 很贊!
Schedulers:Rxjava中除了lift外另外一個很讚的特性
能夠指定Observable和Observer的工做線程。
示例:
Observable.just("http://www.test.com/users")
.flatMap(new Func1<String, Observable<String>>() {
@Override
public Observable<String> call(String s) {
return Observable.just("json string");
}
}).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<String>() {
@Override
public void call(String s) {
mTextView.setText(s);
}
});
這個示例模擬了一個網絡請求,在subscribeOn中設置網絡請求在io線程中執行,observeOn中指定更新TextView在UI主線程中執行。
這裏AndroidSchedulers須要使用RxAndroid庫。
其餘幾個經常使用的方法:
doOnNext:在onNext以前調用,好比須要將服務端返回的數據在顯示到界面前保存等。關於在其中存儲文件阻塞線程的問題,參考:
http://blog.csdn.net/wangkai0681080/article/details/50772721
測試示例:
Observable.just("A").doOnNext(new Action1<String>() {
@Override
public void call(String s) {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.d("Turman",s);
}
}).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1<String>() {
@Override
public void call(String s) {
Toast.makeText(SplashActivity.this,s+"-end",Toast.LENGTH_SHORT).show();
}
});
mergeWith:同類Observable合併 combineLatest:多個Observable組合處理 compose:http://blog.danlew.net/2015/03/02/dont-break-the-chain/ 關於:compose(SplashActivity.this.<Integer>bindUntilEvent(ActivityEvent.DESTROY)) 參考:http://www.open-open.com/lib/view/open1448189551399.html 參考RxBus: http://nerds.weddingpartyapp.com/tech/2014/12/24/implementing-an-event-bus-with-rxjava-rxbus/ 未完待續 2016/07/12