关闭

可能是东半球最全的RxJava使用场景小结

120人阅读 评论(0) 收藏 举报
分类:

一、Scheduler线程切换

这种场景经常会在“后台线程取数据,主线程展示”的模式中看见

[html] view plain copy
  1. Observable.just(1, 2, 3, 4)  
  2.             .subscribeOn(Schedulers.io()) // 指定 subscribe() 发生在 IO 线程  
  3.             .observeOn(AndroidSchedulers.mainThread()) // 指定 Subscriber 的回调发生在主线程  
  4.             .subscribe(new Action1<Integer>() {  
  5.         @Override  
  6.         public void call(Integer number) {  
  7.             Log.d(tag, "number:" + number);  
  8.         }  
  9.     });  

二、使用debounce做textSearch

用简单的话讲就是当N个结点发生的时间太靠近(即发生的时间差小于设定的值T),debounce就会自动过滤掉前N-1个结点。

比如在做百度地址联想的时候,可以使用debounce减少频繁的网络请求。避免每输入(删除)一个字就做一次联想

[html] view plain copy
  1. RxTextView.textChangeEvents(inputEditText)  
  2.       .debounce(400, TimeUnit.MILLISECONDS)   
  3.       .observeOn(AndroidSchedulers.mainThread())  
  4.       .subscribe(new Observer<TextViewTextChangeEvent>() {  
  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讲的比较详细。

五、使用combineLatest合并最近N个结点
例如:注册的时候所有输入信息(邮箱、密码、电话号码等)合法才点亮注册按钮。
  1. Observable<CharSequence> _emailChangeObservable = RxTextView.textChanges(_email).skip(1);  
  2. Observable<CharSequence> _passwordChangeObservable = RxTextView.textChanges(_password).skip(1);  
  3. Observable<CharSequence>   _numberChangeObservable = RxTextView.textChanges(_number).skip(1);  
  4.   
  5. Observable.combineLatest(_emailChangeObservable,  
  6.               _passwordChangeObservable,  
  7.               _numberChangeObservable,  
  8.               new Func3<CharSequence, CharSequence, CharSequence, Boolean>() {  
  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<Boolean>() {  
  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<String>() {  
  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中是否存在数据,任何一步一旦发现数据后面的操作都不执行。

[html] view plain copy
  1. Observable<String> memory = Observable.create(new Observable.OnSubscribe<String>() {  
  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<String> disk = Observable.create(new Observable.OnSubscribe<String>() {  
  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<String> 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”,然后结束。

[html] view plain copy
  1. Observable.timer(2, TimeUnit.SECONDS)  
  2.               .subscribe(new Observer<Long>() {  
  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”。

[html] view plain copy
  1. Observable.interval(2, TimeUnit.SECONDS)  
  2.          .subscribe(new Observer<Long>() {  
  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也能达到同样的效果

[html] view plain copy
  1. RxView.clicks(button)  
  2.               .throttleFirst(1, TimeUnit.SECONDS)  
  3.               .subscribe(new Observer<Object>() {  
  4.                   @Override  
  5.                   public void onCompleted() {  
  6.                         log.d ("completed");  
  7.                   }  
  8.   
  9.                   @Override  
  10.                   public void onError(Throwable e) {  
  11.                         log.e("error");  
  12.                   }  
  13.   
  14.                   @Override  
  15.                   public void onNext(Object o) {  
  16.                        log.d("button clicked");  
  17.                   }  
  18.               });  


十一、使用schedulePeriodically做轮询请求


[html] view plain copy
  1. Observable.create(new Observable.OnSubscribe<String>() {  
  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<String>() {  
  14.             @Override  
  15.             public void call(String s) {  
  16.                 log.d("polling….”));  
  17.             }  
  18.         })  


十二、RxJava进行数组、list的遍历

[html] view plain copy
  1. String[] names = {"Tom", "Lily", "Alisa", "Sheldon", "Bill"};  
  2. Observable  
  3.         .from(names)  
  4.         .subscribe(new Action1<String>() {  
  5.             @Override  
  6.             public void call(String name) {  
  7.                 log.d(name);  
  8.             }  
  9.         });  

十三、解决嵌套回调(callback hell)问题

[html] view plain copy
  1. NetworkService.getToken("username", "password")  
  2.     .flatMap(s -> NetworkService.getMessage(s))  
  3.     .subscribe(s -> {  
  4.         System.out.println("message: " + s);  
  5. })  

十四、响应式的界面

比如勾选了某个checkbox,自动更新对应的preference

[html] view plain copy
  1. SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);  
  2. RxSharedPreferences rxPreferences = RxSharedPreferences.create(preferences);  
  3.   
  4. Preference<Boolean> checked = rxPreferences.getBoolean("checked", true);  
  5.   
  6. CheckBox checkBox = (CheckBox) findViewById(R.id.cb_test);  
  7. RxCompoundButton.checkedChanges(checkBox)  
  8.         .subscribe(checked.asAction());  


最后,由于个人能力有限,文章难免有疏漏之处,如果您有任何疑议,请让我知道,谢谢!本文所有的例子已经上传到github上


致谢:这篇文章的绝大多数例子是从这里总结的,还有部分例子来自这里。对作者的无私贡献表示感谢!

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:1068703次
    • 积分:15173
    • 等级:
    • 排名:第792名
    • 原创:56篇
    • 转载:1657篇
    • 译文:4篇
    • 评论:107条
    文章分类
    最新评论