RxJava
提到Rxjava最多人都是用來處理舍沙,線程調(diào)度嘱腥,回調(diào)地獄州弟,加上Retrofit又支持Rxjava暇咆,所以大部分開發(fā)者都只會在請求網(wǎng)絡(luò)和需要切換線程的時候用到Rxjava,其實它有一個最重要的特性塔插,它可以讓數(shù)據(jù)的流向更加直觀梗摇,代碼更清晰。
舉個栗子
比如說一個龐大的項目想许,一個事件傳遞的整個過程可能要經(jīng)歷很多方法伶授,方法套方法断序,每個方法的位置七零八落,一個個方法跳進去看,跳過去跳過來很容易把腦袋弄暈糜烹,不夠直觀违诗。但是Rxjava可以把所有邏輯用鏈式加閉包的方式呈現(xiàn),做了哪些操作疮蹦,誰在前誰在后非常直觀诸迟,邏輯清晰,維護就會非常輕松愕乎。就算不是你寫的你也可以很快的了解阵苇,你可以把它看作一條河流,整個過程就是對里面的水流做進行加工感论。懂了這個特性我們才知道在復雜的邏輯中運用Rxjava是多么的重要绅项。
Gradle添加依賴
要在Android中使用RxJava2, 先添加Gradle配置。
compile "io.reactivex.rxjava2:rxjava:2.0.7"
compile "io.reactivex.rxjava2:rxandroid:2.0.1"
一個簡單實例(分別創(chuàng)建被觀察者比肄,觀察者和兩種對象進行關(guān)聯(lián))
//創(chuàng)建被觀察者
Observable<String> observable = Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
//調(diào)用觀察者的回調(diào)
emitter.onNext("我是");
emitter.onNext("RxJava");
emitter.onNext("簡單示例");
emitter.onError(new Throwable("出錯了"));
emitter.onComplete();
}
});
//創(chuàng)建觀察者
Observer<String> observer = new Observer<String>() {
@Override
public void onError(Throwable e) {
Log.e(TAG,e.getMessage());
}
@Override
public void onComplete() {
Log.e(TAG,"onCompleted");
}
//onSubscribe()方法是最先調(diào)用的
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG,"subscribe");
}
@Override
public void onNext(String s) {
Log.d(TAG,s);
}
};
//注冊快耿,將觀察者和被觀察者關(guān)聯(lián),將會觸發(fā)OnSubscribe.call方法
observable.subscribe(observer);
運行結(jié)果:
Observable是被觀察者芳绩,創(chuàng)建后傳入一個OnSubscribe對象掀亥,當Observable(觀察者)調(diào)用subscribe進行注冊觀察者時,OnSubscribe的call方法會觸發(fā)妥色。
ObservableEmitter: Emitter 是發(fā)射器的意思搪花,它可以發(fā)出三種類型的事件,與之對應的垛膝。
Observer有三個回調(diào)方法:
- onNext:接受到一個事件
- onCompleted:接受完事件后調(diào)用鳍侣,只會調(diào)用一次
- onError :發(fā)生錯誤時調(diào)用,并停止接受事件吼拥,調(diào)用一次
注:onCompleted和onError不會同時調(diào)用倚聚,只會調(diào)用其中之一
另一個簡單實例(訪問網(wǎng)絡(luò)時,通過RxJava來進行快捷的主線程和子線程切換)
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView tv_return = (TextView) findViewById(R.id.tv_return);
//創(chuàng)建被觀察者
Observable<String> observable = Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
Log.d(TAG, "Observer thread is :" + Thread.currentThread().getName());
emitter.onNext(getResponse());
}
});
//創(chuàng)建觀察者
Consumer<String> consumer = new Consumer<String>() {
@Override
public void accept(String mResponse) throws Exception {
Log.d(TAG, "Observer thread is :" + Thread.currentThread().getName());
tv_return.setText(mResponse);
}
};
//subscribeOn() 指定的是發(fā)送事件的線程, observeOn() 指定的是接收事件的線程.
observable.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(consumer);
}
//使用okhttp訪問網(wǎng)上提供的接口凿可,由于是同步get請求惑折,需要在子線程進行
private String getResponse() {
String url = "http://v.juhe.cn/weather/index?cityname=%E6%9D%AD%E5%B7%9E&dtype=&format=&key=7970495dbf33839562c9d496156e13cc";
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(url)
.build();
Response response;
try {
response = client.newCall(request).execute();
return response.body().string();
} catch (IOException e) {
return "error";
}
}
在RxJava中, 已經(jīng)內(nèi)置了很多線程選項供我們選擇, 例如有
- Schedulers.io() 代表io操作的線程, 通常用于網(wǎng)絡(luò),讀寫文件等io密集型的操作
- Schedulers.computation() 代表CPU計算密集型的操作, 例如需要大量計算的操作
- Schedulers.newThread() 代表一個常規(guī)的新線程
- AndroidSchedulers.mainThread() 代表Android的主線程
這些內(nèi)置的Scheduler已經(jīng)足夠滿足我們開發(fā)的需求, 因此我們應該使用內(nèi)置的這些選項枯跑,在RxJava內(nèi)部使用的是線程池來維護這些線程惨驶,所有效率也比較高。
第三個簡單實例(類型變換操作)
RxJava提供了類型變換操作敛助,像上面的發(fā)送網(wǎng)絡(luò)請求事件粗卜,得到網(wǎng)絡(luò)請求數(shù)據(jù),傳遞和接收的都是字符串纳击。
而RxJava中的map操作符可以對事件進行處理续扔,比如發(fā)送網(wǎng)絡(luò)請求事件攻臀,通過map處理后,可以接收到網(wǎng)絡(luò)請求的字符串的字節(jié)數(shù)纱昧,如下所示刨啸。
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView tv_return = (TextView) findViewById(R.id.tv_return);
//創(chuàng)建被觀察者
Observable<Integer> observable = Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
Log.d(TAG, "Observer thread is :" + Thread.currentThread().getName());
emitter.onNext(getResponse());
}
//通過map操作符對數(shù)據(jù)進行中間處理
}).map(new Function<String, Integer>() {
@Override
public Integer apply(@NonNull String response) throws Exception {
return response.length();
}
});
//創(chuàng)建觀察者
Consumer<Integer> consumer = new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
Log.d(TAG, "Observer thread is :" + Thread.currentThread().getName());
tv_return.setText("字數(shù):"+integer);
}
};
//綁定,指定線程
observable.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(consumer);
}
第四個簡單實例(鏈式操作)
而RxJava一個引以為豪的地方就是它的鏈式操作了识脆,可以把被觀察者和觀察者串起來设联。
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView tv_return = (TextView) findViewById(R.id.tv_return);
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
Log.d(TAG, "Observer thread is :" + Thread.currentThread().getName());
emitter.onNext(getResponse());
}
}).map(new Function<String, Integer>() {
@Override
public Integer apply(@NonNull String response) throws Exception {
return response.length();
}
}).subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<Integer>() {
@Override
public void accept(@NonNull Integer integer) throws Exception {
Log.d(TAG, "Observer thread is :" + Thread.currentThread().getName());
tv_return.setText("字數(shù):" + integer);
}
});
}
這里是項目地址 其實也沒啥東西
喜歡的同學可以點個贊
參考
https://xiaobailong24.me/2017/03/18/Android-RxJava2.x/
http://www.reibang.com/p/6fd8640046f1