【转】https://blog.csdn.net/theone10211024/article/details/50435325
一、Scheduler线程切换
这种场景经常会在“后台线程取数据,主线程展示”的模式中看见
1. Observable.just(1, 2, 3, 4)
2. .subscribeOn(Schedulers.io()) // 指定 subscribe() 发生在 IO 线程
3. .observeOn(AndroidSchedulers.mainThread()) // 指定 Subscriber 的回调发生在主线程
4. .subscribe(new Action1() {
5. @Override
6. public void call(Integer number) {
7. Log.d(tag, "number:" + number);
8. }
9. });
二、使用debounce做textSearch
用简单的话讲就是当N个结点发生的时间太靠近(即发生的时间差小于设定的值T),debounce就会自动过滤掉前N-1个结点。
比如在做百度地址联想的时候,可以使用debounce减少频繁的网络请求。避免每输入(删除)一个字就做一次联想
1. RxTextView.textChangeEvents(inputEditText)
2. .debounce(400, TimeUnit.MILLISECONDS)
3. .observeOn(AndroidSchedulers.mainThread())
4. .subscribe(new Observer() {
5. @Override
6. public void onCompleted() {
7. log.d("onComplete");
8. }
9.
10. @Override
11. public void onError(Throwable e) {
12. log.d("Error");
13. }
14.
15. @Override
16. public void onNext(TextViewTextChangeEvent onTextChangeEvent) {
17. log.d(format("Searching for %s", onTextChangeEvent.text().toString()));
18. }
19. });
三、Retrofit结合RxJava做网络请求框架
这里不作详解,具体的介绍可以看扔物线的这篇文章,对RxJava的入门者有很大的启发。其中也讲到了RxJava和Retrofit如何结合来实现更简洁的代码
四、RxJava代替EventBus进行数据传递:RxBus
注意:RxBus并不是一个库,而是一种模式,是使用了RxJava的思想来达到EventBus的数据传递效果。这篇文章把RxBus讲的比较详细http://nerds.weddingpartyapp.com/tech/2014/12/24/implementing-an-event-bus-with-rxjava-rxbus/。
五、使用combineLatest合并最近N个结点
例如:注册的时候所有输入信息(邮箱、密码、电话号码等)合法才点亮注册按钮。
1. Observable _emailChangeObservable = RxTextView.textChanges(_email).skip(1);
2. Observable _passwordChangeObservable = RxTextView.textChanges(_password).skip(1);
3. Observable _numberChangeObservable = RxTextView.textChanges(_number).skip(1);
4.
5. Observable.combineLatest(_emailChangeObservable,
6. _passwordChangeObservable,
7. _numberChangeObservable,
8. new Func3() {
9. @Override
10. public Boolean call(CharSequence newEmail,
11. CharSequence newPassword,
12. CharSequence newNumber) {
13.
14. Log.d("xiayong",newEmail+" "+newPassword+" "+newNumber);
15. boolean emailValid = !isEmpty(newEmail) &&
16. EMAIL_ADDRESS.matcher(newEmail).matches();
17. if (!emailValid) {
18. _email.setError("Invalid Email!");
19. }
20.
21. boolean passValid = !isEmpty(newPassword) && newPassword.length() > 8;
22. if (!passValid) {
23. _password.setError("Invalid Password!");
24. }
25.
26. boolean numValid = !isEmpty(newNumber);
27. if (numValid) {
28. int num = Integer.parseInt(newNumber.toString());
29. numValid = num > 0 && num <= 100;
30. }
31. if (!numValid) {
32. _number.setError("Invalid Number!");
33. }
34.
35. return emailValid && passValid && numValid;
36.
37. }
38. })//
39. .subscribe(new Observer() {
40. @Override
41. public void onCompleted() {
42. log.d("completed");
43. }
44.
45. @Override
46. public void onError(Throwable e) {
47. log.d("Error");
48. }
49.
50. @Override
51. public void onNext(Boolean formValid) {
52. _btnValidIndicator.setEnabled(formValid);
53. }
54. });
六、使用merge合并两个数据源。
例如一组数据来自网络,一组数据来自文件,需要合并两组数据一起展示。
1. Observable.merge(getDataFromFile(), getDataFromNet())
2. .observeOn(AndroidSchedulers.mainThread())
3. .subscribe(new Subscriber() {
4. @Override
5. public void onCompleted() {
6. log.d("done loading all data");
7. }
8.
9. @Override
10. public void onError(Throwable e) {
11. log.d("error");
12. }
13.
14. @Override
15. public void onNext(String data) {
16. log.d("all merged data will pass here one by one!")
17. });
七、使用concat和first做缓存
依次检查memory、disk和network中是否存在数据,任何一步一旦发现数据后面的操作都不执行。
1. Observable memory = Observable.create(new Observable.OnSubscribe() {
2. @Override
3. public void call(Subscriber super String> subscriber) {
4. if (memoryCache != null) {
5. subscriber.onNext(memoryCache);
6. } else {
7. subscriber.onCompleted();
8. }
9. }
10. });
11. Observable disk = Observable.create(new Observable.OnSubscribe() {
12. @Override
13. public void call(Subscriber super String> subscriber) {
14. String cachePref = rxPreferences.getString("cache").get();
15. if (!TextUtils.isEmpty(cachePref)) {
16. subscriber.onNext(cachePref);
17. } else {
18. subscriber.onCompleted();
19. }
20. }
21. });
22.
23. Observable network = Observable.just("network");
24.
25. //依次检查memory、disk、network
26. Observable.concat(memory, disk, network)
27. .first()
28. .subscribeOn(Schedulers.newThread())
29. .subscribe(s -> {
30. memoryCache = "memory";
31. System.out.println("--------------subscribe: " + s);
32. });
八、使用timer做定时操作。当有“x秒后执行y操作”类似的需求的时候,想到使用timer
例如:2秒后输出日志“hello world”,然后结束。
1. Observable.timer(2, TimeUnit.SECONDS)
2. .subscribe(new Observer() {
3. @Override
4. public void onCompleted() {
5. log.d ("completed");
6. }
7.
8. @Override
9. public void onError(Throwable e) {
10. log.e("error");
11. }
12.
13. @Override
14. public void onNext(Long number) {
15. log.d ("hello world");
16. }
17. });
九、使用interval做周期性操作。当有“每隔xx秒后执行yy操作”类似的需求的时候,想到使用interval
例如:每隔2秒输出日志“helloworld”。
1. Observable.interval(2, TimeUnit.SECONDS)
2. .subscribe(new Observer() {
3. @Override
4. public void onCompleted() {
5. log.d ("completed");
6. }
7.
8. @Override
9. public void onError(Throwable e) {
10. log.e("error");
11. }
12.
13. @Override
14. public void onNext(Long number) {
15. log.d ("hello world");
16. }
17. });
十、使用throttleFirst防止按钮重复点击
ps:debounce也能达到同样的效果
1. RxView.clicks(button)
2. .throttleFirst(1, TimeUnit.SECONDS)
3. .subscribe(new Observer
十一、使用schedulePeriodically做轮询请求
1. Observable.create(new Observable.OnSubscribe() {
2. @Override
3. public void call(final Subscriber super String> observer) {
4.
5. Schedulers.newThread().createWorker()
6. .schedulePeriodically(new Action0() {
7. @Override
8. public void call() {
9. observer.onNext(doNetworkCallAndGetStringResult());
10. }
11. }, INITIAL_DELAY, POLLING_INTERVAL, TimeUnit.MILLISECONDS);
12. }
13. }).subscribe(new Action1() {
14. @Override
15. public void call(String s) {
16. log.d("polling….”));
17. }
18. })
十二、RxJava进行数组、list的遍历
1. String[] names = {"Tom", "Lily", "Alisa", "Sheldon", "Bill"};
2. Observable
3. .from(names)
4. .subscribe(new Action1() {
5. @Override
6. public void call(String name) {
7. log.d(name);
8. }
9. });
十三、解决嵌套回调(callback hell)问题
1. NetworkService.getToken("username", "password")
2. .flatMap(s -> NetworkService.getMessage(s))
3. .subscribe(s -> {
4. System.out.println("message: " + s);
5. })
十四、响应式的界面
比如勾选了某个checkbox,自动更新对应的preference
1. SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
2. RxSharedPreferences rxPreferences = RxSharedPreferences.create(preferences);
3.
4. Preference checked = rxPreferences.getBoolean("checked", true);
5.
6. CheckBox checkBox = (CheckBox) findViewById(R.id.cb_test);
7. RxCompoundButton.checkedChanges(checkBox)
8. .subscribe(checked.asAction());
最后,由于个人能力有限,文章难免有疏漏之处,如果您有任何疑议,请让我知道,谢谢!本文所有的例子已经上传到github上https://github.com/THEONE10211024/RxJavaSamples
致谢:这篇文章的绝大多数例子是从这里https://github.com/kaushikgopal/RxJava-Android-Samples总结的,还有部分例子来自这里http://blog.csdn.net/lzyzsd/article/details/50120801。对作者的无私贡献表示感谢!