一、Map操作符
map是RxJava中最簡(jiǎn)單的一個(gè)變換操作符了, 它的作用就是對(duì)上游發(fā)送的每一個(gè)事件應(yīng)用一個(gè)函數(shù), 使得每一個(gè)事件都按照指定的函數(shù)去變化。
這邊直接以代碼的形式去展示下map操作符的使用:
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(10);
emitter.onNext(20);
emitter.onNext(30);
}
}).map(new Function<Integer, String>() {
@Override
public String apply(Integer integer) throws Exception {
return "接收到:"+integer;
}
}).subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.e(TAG, s);
}
});
}
看下打印結(jié)果:
11-28 15:17:58.233 14116-14116/com.example.qidong.testrxjava E/MainActivity: 接收到:10
11-28 15:17:58.234 14116-14116/com.example.qidong.testrxjava E/MainActivity: 接收到:20
11-28 15:17:58.234 14116-14116/com.example.qidong.testrxjava E/MainActivity: 接收到:30
被觀察者發(fā)送的是Integer類(lèi)型的數(shù)據(jù),經(jīng)過(guò)map變換之后,觀察者接收到的是String類(lèi)型的數(shù)據(jù)。通過(guò)Map, 可以將上游發(fā)來(lái)的事件轉(zhuǎn)換為任意的類(lèi)型, 可以是一個(gè)Object, 也可以是一個(gè)集合,功能是非常的強(qiáng)大。
二、flatMap操作符
FlatMap將一個(gè)發(fā)送事件的上游Observable變換為多個(gè)發(fā)送事件的Observables,然后將它們發(fā)射的事件合并后放進(jìn)一個(gè)單獨(dú)的Observable里。
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
}
}).flatMap(new Function<Integer, ObservableSource<String>>() {
@Override
public ObservableSource<String> apply(Integer integer) throws Exception {
List<String> list=new ArrayList<>();
for(int i=0;i<3;i++)
{
list.add(integer+":"+i);
}
//延遲5秒
return Observable.fromIterable(list).delay(10, TimeUnit.MILLISECONDS);
}
}).subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.e(TAG,s);
}
});
如代碼所示, 我們?cè)趂latMap中將上游發(fā)來(lái)的每個(gè)事件轉(zhuǎn)換為一個(gè)新的發(fā)送三個(gè)String事件的水管, 為了看到flatMap結(jié)果是無(wú)序的,所以加了10毫秒的延時(shí), 來(lái)看看運(yùn)行結(jié)果吧:
11-28 15:38:40.751 16137-16208/com.example.qidong.testrxjava E/MainActivity: 2:0
11-28 15:38:40.756 16137-16208/com.example.qidong.testrxjava E/MainActivity: 2:1
11-28 15:38:40.756 16137-16208/com.example.qidong.testrxjava E/MainActivity: 2:2
11-28 15:38:40.759 16137-16209/com.example.qidong.testrxjava E/MainActivity: 3:0
11-28 15:38:40.764 16137-16209/com.example.qidong.testrxjava E/MainActivity: 3:1
11-28 15:38:40.765 16137-16209/com.example.qidong.testrxjava E/MainActivity: 3:2
11-28 15:38:40.767 16137-16206/com.example.qidong.testrxjava E/MainActivity: 1:0
11-28 15:38:40.767 16137-16206/com.example.qidong.testrxjava E/MainActivity: 1:1
11-28 15:38:40.767 16137-16206/com.example.qidong.testrxjava E/MainActivity: 1:2
打印的結(jié)果正如我們所想的那樣。
三、concatMap操作符
concatMap操作符的作用和flatMap的作用差不多,不同點(diǎn)在于它的結(jié)果是嚴(yán)格按照被觀察者發(fā)送事件的順序。下面看一下代碼:
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
}
}).concatMap(new Function<Integer, ObservableSource<String>>() {
@Override
public ObservableSource<String> apply(Integer integer) throws Exception {
List<String> list=new ArrayList<>();
for(int i=0;i<3;i++)
{
list.add(integer+":"+i);
}
//延遲5秒
return Observable.fromIterable(list).delay(10, TimeUnit.MILLISECONDS);
}
}).subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.e(TAG,s);
}
});
運(yùn)行結(jié)果:
11-28 15:57:45.873 18765-18835/com.example.qidong.testrxjava E/MainActivity: 1:0
11-28 15:57:45.873 18765-18835/com.example.qidong.testrxjava E/MainActivity: 1:1
11-28 15:57:45.874 18765-18835/com.example.qidong.testrxjava E/MainActivity: 1:2
11-28 15:57:45.892 18765-18836/com.example.qidong.testrxjava E/MainActivity: 2:0
11-28 15:57:45.893 18765-18836/com.example.qidong.testrxjava E/MainActivity: 2:1
11-28 15:57:45.896 18765-18836/com.example.qidong.testrxjava E/MainActivity: 2:2
11-28 15:57:45.908 18765-18839/com.example.qidong.testrxjava E/MainActivity: 3:0
11-28 15:57:45.909 18765-18839/com.example.qidong.testrxjava E/MainActivity: 3:1
11-28 15:57:45.910 18765-18839/com.example.qidong.testrxjava E/MainActivity: 3:2
可以看到結(jié)果是有序的。
四、實(shí)例應(yīng)用
以一個(gè)虛擬的注冊(cè)登錄請(qǐng)求為例,用RxJava結(jié)合Retrofit來(lái)實(shí)現(xiàn)這樣的功能。
public interface Api {
@GET
Observable<LoginResponse> login(@Body LoginRequest request);
@GET
Observable<RegisterResponse> register(@Body RegisterRequest request);
}
可以看到登錄和注冊(cè)返回的都是一個(gè)上游Observable, 而我們的flatMap操作符的作用就是把一個(gè)Observable轉(zhuǎn)換為另一個(gè)Observable, 因此結(jié)果就很顯而易見(jiàn)了:
api.register(new RegisterRequest()) //發(fā)起注冊(cè)請(qǐng)求
.subscribeOn(Schedulers.io()) //在IO線(xiàn)程進(jìn)行網(wǎng)絡(luò)請(qǐng)求
.observeOn(AndroidSchedulers.mainThread()) //回到主線(xiàn)程去處理請(qǐng)求注冊(cè)結(jié)果
.doOnNext(new Consumer<RegisterResponse>() {
@Override
public void accept(RegisterResponse registerResponse) throws Exception {
//先根據(jù)注冊(cè)的響應(yīng)結(jié)果去做一些操作
}
})
.observeOn(Schedulers.io()) //回到IO線(xiàn)程去發(fā)起登錄請(qǐng)求
.flatMap(new Function<RegisterResponse, ObservableSource<LoginResponse>>() {
@Override
public ObservableSource<LoginResponse> apply(RegisterResponse registerResponse) throws Exception {
return api.login(new LoginRequest());
}
})
.observeOn(AndroidSchedulers.mainThread()) //回到主線(xiàn)程去處理請(qǐng)求登錄的結(jié)果
.subscribe(new Consumer<LoginResponse>() {
@Override
public void accept(LoginResponse loginResponse) throws Exception {
Toast.makeText(MainActivity.this, "登錄成功", Toast.LENGTH_SHORT).show();
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
Toast.makeText(MainActivity.this, "登錄失敗", Toast.LENGTH_SHORT).show();
}
});
從這個(gè)例子也可以看到我們切換線(xiàn)程是多么簡(jiǎn)單.