注:本文摘自《RxJava Essentials》翻譯中文版電子書
開頭
引用的例子:檢索安裝的應(yīng)用列表并填充RecycleView的item來展示它們:
private Observable<AppInfo> getApps(){
return Observable.create(subscriber -> {
List<AppInfoRich> apps = new ArrayList<AppInfoRich>();
final Intent mainIntent = new Intent(Intent.ACTION_MAIN,null);
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
List<ResolveInfo> infos = getActivity().getPackageManager().queryIntentActivities(mainIntent, 0);
for(ResolveInfo info : infos){
apps.add(new AppInfoRich(getActivity(),info));
}
for (AppInfoRich appInfo:apps) {
Bitmap icon = Utils.drawableToBitmap(appInfo.getIcon());
String name = appInfo.getName();
String iconPath = mFilesDir + "/" + name;
Utils.storeBitmap(App.instance, icon,name);
if (subscriber.isUnsubscribed()){
return;
}
subscriber.onNext(new AppInfo(name,iconPath,appInfo.getLastUpdateTime()));
}
if (!subscriber.isUnsubscribed()){
subscriber.onCompleted();
}
});
}
重點注意的是在發(fā)射新的數(shù)據(jù)( subscriber.onNext())或者完成序列之前( subscriber.onCompleted())要檢測觀察者的訂閱情況乏矾。這樣的話代碼會更高效蝶棋,因為如果沒有觀察者等待時我們就不生成沒有必要的數(shù)據(jù)項顽聂。
from()
如果希望Observable發(fā)射的是整個list,那么可以這樣做:
mApps = ApplicationsList.getInstance().getList();
private void loadList(List<AppInfo> apps) {
Observable.from(apps).subscribe(/**代碼省略**/);
}
just()
假如我們只有3個獨立的AppInfo對象并且我們想把他們轉(zhuǎn)化為Observable并填充到RecyclerView的item中:
private void loadApps(AppInfo appOne,AppInfo appTwo,AppInfo appThree) {
Observable.just(appOne,appTwo,appThree).subscribe(/**代碼省略**/);
}
你可以將一個函數(shù)作為參數(shù)傳給just()方法博其,你將會得到一個已存在代碼的原始Observable版本。在一個新的響應(yīng)式架構(gòu)的基礎(chǔ)上遷移已存在的代碼立肘。
repeat()
假如你想對一個Observable重復(fù)發(fā)射三次數(shù)據(jù):
private void loadApps(AppInfo appOne,AppInfo appTwo,AppInfo appThree) {
Observable.just(appOne,appTwo,appThree)
.repeat(3)
.subscribe(/**代碼省略**/);
}
我們在just()創(chuàng)建Observable后追加了repeat(3)铲球,它將會創(chuàng)建9個元素的序列,每一個都單獨發(fā)射谁尸。
defer()
有這樣一個場景舅踪,你想在這聲明一個Observable但是你又想推遲這個Observable的創(chuàng)建直到觀察者訂閱時×悸看下面的getInt()函數(shù):
private Observable<Integer> getInt(){
return Observable.create(subscriber -> {
if(subscriber.isUnsubscribed()){
return;
}
App.L.debug("GETINT");
subscriber.onNext(42);
subscriber.onCompleted();
});
}
這比較簡單抽碌,并且它沒有做太多事情,但是它正好為我們服務(wù)【鐾現(xiàn)在货徙,我們可以創(chuàng)建一個新的Observable并且應(yīng)用defer():
Observable<Integer> deferred = Observable.defer(this::getInt);
這次左权,deferred存在,但是getInt() create()方法還沒有調(diào)用:logcat日志也沒有“GETINT”打印出來:
deferred.subscribe(number -> {
App.L.debug(String.valueOf(number));
});
但是一旦我們訂閱了痴颊,create()方法就會被調(diào)用并且我們也可以在logcat日志中得到下賣弄兩個:GETINT和42赏迟。
range()
如果需要從一個指定的數(shù)字X開始發(fā)射N個數(shù)字,可以用它:
Observable.range(10,3).subscribe(/**代碼省略**/);
range()函數(shù)用兩個數(shù)字作為參數(shù):第一個是起始點祷舀,第二個是我們想發(fā)射數(shù)字的個數(shù)瀑梗。
interval()
interval()函數(shù)在你需要創(chuàng)建一個輪詢程序時非常好用。
Subscription stopMePlease = Observable.interval(3,TimeUnit.SECONDS)
.subscribe(/**代碼省略**/);
interval()函數(shù)的兩個參數(shù):一個指定兩次發(fā)射的時間間隔裳扯,另一個是用到的時間單位抛丽。
timer()
如果你需要一個一段時間之后才發(fā)射的Observable,你可以像下面的例子使用timer():
Observable.timer(3,TimeUnit.SECONDS)
.subscribe(/**代碼省略**/);
它將3秒后發(fā)射0,然后就完成了饰豺。讓我們使用timer()的第三個參數(shù)亿鲜,就像下面的例子:
Observable.timer(3,3,TimeUnit.SECONDS)
.subscribe(/**代碼省略**/);
用這個代碼,你可以創(chuàng)建一個以初始值來延遲執(zhí)行的interval()版本冤吨,然后每隔N秒就發(fā)射一個新的數(shù)字蒿柳。