原文鏈接 http://blog.csdn.net/theone10211024/article/details/50435325
一、Scheduler線程切換
這種場(chǎng)景經(jīng)常會(huì)在“后臺(tái)線程取數(shù)據(jù)包斑,主線程展示”的模式中看見
[html]view plaincopy
Observable.just(1,?2,?3,?4)
.subscribeOn(Schedulers.io())?//?指定?subscribe()?發(fā)生在?IO?線程
.observeOn(AndroidSchedulers.mainThread())?//?指定?Subscriber?的回調(diào)發(fā)生在主線程
.subscribe(new?Action1()?{
@Override
public?void?call(Integer?number)?{
Log.d(tag,?"number:"?+?number);
}
});
二、使用debounce做textSearch
用簡(jiǎn)單的話講就是當(dāng)N個(gè)結(jié)點(diǎn)發(fā)生的時(shí)間太靠近(即發(fā)生的時(shí)間差小于設(shè)定的值T)捶枢,debounce就會(huì)自動(dòng)過濾掉前N-1個(gè)結(jié)點(diǎn)浑侥。
比如在做百度地址聯(lián)想的時(shí)候尖淘,可以使用debounce減少頻繁的網(wǎng)絡(luò)請(qǐng)求昌阿。避免每輸入(刪除)一個(gè)字就做一次聯(lián)想
[html]view plaincopy
RxTextView.textChangeEvents(inputEditText)
.debounce(400,?TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new?Observer()?{
@Override
public?void?onCompleted()?{
log.d("onComplete");
}
@Override
public?void?onError(Throwable?e)?{
log.d("Error");
}
@Override
public?void?onNext(TextViewTextChangeEvent?onTextChangeEvent)?{
log.d(format("Searching?for?%s",?onTextChangeEvent.text().toString()));
}
});
三殖告、Retrofit結(jié)合RxJava做網(wǎng)絡(luò)請(qǐng)求框架
這里不作詳解烘挫,具體的介紹可以看扔物線的這篇文章诀艰,對(duì)RxJava的入門者有很大的啟發(fā)。其中也講到了RxJava和Retrofit如何結(jié)合來實(shí)現(xiàn)更簡(jiǎn)潔的代碼
四饮六、RxJava代替EventBus進(jìn)行數(shù)據(jù)傳遞:RxBus
注意:RxBus并不是一個(gè)庫(kù)其垄,而是一種模式,是使用了RxJava的思想來達(dá)到EventBus的數(shù)據(jù)傳遞效果卤橄。這篇文章把RxBus講的比較詳細(xì)绿满。
五、使用combineLatest合并最近N個(gè)結(jié)點(diǎn)
例如:注冊(cè)的時(shí)候所有輸入信息(郵箱窟扑、密碼喇颁、電話號(hào)碼等)合法才點(diǎn)亮注冊(cè)按鈕。
[html]view plaincopy
Observable_emailChangeObservable=RxTextView.textChanges(_email).skip(1);
Observable_passwordChangeObservable=RxTextView.textChanges(_password).skip(1);
Observable_numberChangeObservable=RxTextView.textChanges(_number).skip(1);
Observable.combineLatest(_emailChangeObservable,
_passwordChangeObservable,
_numberChangeObservable,
new?Func3()?{
@Override
public?Boolean?call(CharSequence?newEmail,
CharSequence?newPassword,
CharSequence?newNumber)?{
Log.d("xiayong",newEmail+"?"+newPassword+"?"+newNumber);
booleanemailValid=?!isEmpty(newEmail)?&&
EMAIL_ADDRESS.matcher(newEmail).matches();
if?(!emailValid)?{
_email.setError("Invalid?Email!");
}
booleanpassValid=?!isEmpty(newPassword)?&&?newPassword.length()>8;
if?(!passValid)?{
_password.setError("Invalid?Password!");
}
booleannumValid=?!isEmpty(newNumber);
if?(numValid)?{
intnum=Integer.parseInt(newNumber.toString());
numValid=num>0?&&?num<=?100;
}
if?(!numValid)?{
_number.setError("Invalid?Number!");
}
return?emailValid?&&?passValid?&&?numValid;
}
})//
.subscribe(new?Observer()?{
@Override
public?void?onCompleted()?{
log.d("completed");
}
@Override
public?void?onError(Throwable?e)?{
log.d("Error");
}
@Override
public?void?onNext(Boolean?formValid)?{
_btnValidIndicator.setEnabled(formValid);
}
});
六嚎货、使用merge合并兩個(gè)數(shù)據(jù)源橘霎。
例如一組數(shù)據(jù)來自網(wǎng)絡(luò),一組數(shù)據(jù)來自文件殖属,需要合并兩組數(shù)據(jù)一起展示姐叁。
[html]view plaincopy
Observable.merge(getDataFromFile(),?getDataFromNet())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new?Subscriber()?{
@Override
public?void?onCompleted()?{
log.d("done?loading?all?data");
}
@Override
public?void?onError(Throwable?e)?{
log.d("error");
}
@Override
public?void?onNext(String?data)?{
log.d("all?merged?data?will?pass?here?one?by?one!")
});
七、使用concat和first做緩存
依次檢查memory洗显、disk和network中是否存在數(shù)據(jù)外潜,任何一步一旦發(fā)現(xiàn)數(shù)據(jù)后面的操作都不執(zhí)行。
[html]view plaincopy
Observablememory=Observable.create(new?Observable.OnSubscribe()?{
@Override
public?void?call(Subscribersubscriber)?{
if?(memoryCache?!=?null)?{
subscriber.onNext(memoryCache);
}?else?{
subscriber.onCompleted();
}
}
});
Observabledisk=Observable.create(new?Observable.OnSubscribe()?{
@Override
public?void?call(Subscribersubscriber)?{
StringcachePref=rxPreferences.getString("cache").get();
if?(!TextUtils.isEmpty(cachePref))?{
subscriber.onNext(cachePref);
}?else?{
subscriber.onCompleted();
}
}
});
Observablenetwork=Observable.just("network");
//依次檢查memory墙懂、disk橡卤、network
Observable.concat(memory,?disk,?network)
.first()
.subscribeOn(Schedulers.newThread())
.subscribe(s?->{
memoryCache="memory";
System.out.println("--------------subscribe:?"?+?s);
});
八、使用timer做定時(shí)操作损搬。當(dāng)有“x秒后執(zhí)行y操作”類似的需求的時(shí)候碧库,想到使用timer
例如:2秒后輸出日志“hello world”,然后結(jié)束巧勤。
[html]view plaincopy
Observable.timer(2,?TimeUnit.SECONDS)
.subscribe(new?Observer()?{
@Override
public?void?onCompleted()?{
log.d?("completed");
}
@Override
public?void?onError(Throwable?e)?{
log.e("error");
}
@Override
public?void?onNext(Long?number)?{
log.d?("hello?world");
}
});
九嵌灰、使用interval做周期性操作。當(dāng)有“每隔xx秒后執(zhí)行yy操作”類似的需求的時(shí)候颅悉,想到使用interval
例如:每隔2秒輸出日志“helloworld”沽瞭。
[html]view plaincopy
Observable.interval(2,?TimeUnit.SECONDS)
.subscribe(new?Observer()?{
@Override
public?void?onCompleted()?{
log.d?("completed");
}
@Override
public?void?onError(Throwable?e)?{
log.e("error");
}
@Override
public?void?onNext(Long?number)?{
log.d?("hello?world");
}
});
十、使用throttleFirst防止按鈕重復(fù)點(diǎn)擊
ps:debounce也能達(dá)到同樣的效果
[html]view plaincopy
RxView.clicks(button)
.throttleFirst(1,?TimeUnit.SECONDS)
.subscribe(new?Observer()?{
@Override
public?void?onCompleted()?{
log.d?("completed");
}
@Override
public?void?onError(Throwable?e)?{
log.e("error");
}
@Override
public?void?onNext(Object?o)?{
log.d("button?clicked");
}
});
十一剩瓶、使用schedulePeriodically做輪詢請(qǐng)求
[html]view plaincopy
Observable.create(new?Observable.OnSubscribe()?{
@Override
public?void?call(final?Subscriberobserver)?{
Schedulers.newThread().createWorker()
.schedulePeriodically(new?Action0()?{
@Override
public?void?call()?{
observer.onNext(doNetworkCallAndGetStringResult());
}
},?INITIAL_DELAY,?POLLING_INTERVAL,?TimeUnit.MILLISECONDS);
}
}).subscribe(new?Action1()?{
@Override
public?void?call(String?s)?{
log.d("polling….”));
}
})
十二驹溃、RxJava進(jìn)行數(shù)組城丧、list的遍歷
[html]view plaincopy
String[]names=?{"Tom",?"Lily",?"Alisa",?"Sheldon",?"Bill"};
Observable
.from(names)
.subscribe(new?Action1()?{
@Override
public?void?call(String?name)?{
log.d(name);
}
});
十三、解決嵌套回調(diào)(callback hell)問題
[html]view plaincopy
NetworkService.getToken("username",?"password")
.flatMap(s?->NetworkService.getMessage(s))
.subscribe(s?->{
System.out.println("message:?"?+?s);
})
十四豌鹤、響應(yīng)式的界面
比如勾選了某個(gè)checkbox亡哄,自動(dòng)更新對(duì)應(yīng)的preference
[html]view plaincopy
SharedPreferencespreferences=PreferenceManager.getDefaultSharedPreferences(this);
RxSharedPreferencesrxPreferences=RxSharedPreferences.create(preferences);
Preferencechecked=rxPreferences.getBoolean("checked",?true);
CheckBoxcheckBox=?(CheckBox)?findViewById(R.id.cb_test);
RxCompoundButton.checkedChanges(checkBox)
.subscribe(checked.asAction());
最后,由于個(gè)人能力有限布疙,文章難免有疏漏之處蚊惯,如果您有任何疑議,請(qǐng)讓我知道灵临,謝謝截型!本文所有的例子已經(jīng)上傳到github上
致謝:這篇文章的絕大多數(shù)例子是從這里總結(jié)的,還有部分例子來自這里儒溉。對(duì)作者的無私貢獻(xiàn)表示感謝宦焦!