一、Scheduler线程切换

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


[html]  view plain copy



1. Observable.just(1, 2, 3, 4)  
2.             .subscribeOn(Schedulers.io()) // 指定 subscribe() 发生在 IO 线程  
3.             .observeOn(AndroidSchedulers.mainThread()) // 指定 Subscriber 的回调发生在主线程  
4. <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. <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个结点例如:注册的时候所有输入信息(邮箱、密码、电话号码等)合法才点亮注册按钮。
   
   
    
    
     
     
      
      [html] 
      
      view plain
      
      copy
      
      
     
     
    
    
    
    
Observable<CharSequence> _emailChangeObservable = RxTextView.textChanges(_email).skip(1);  
 
Observable<CharSequence> _passwordChangeObservable = RxTextView.textChanges(_password).skip(1);  
 
Observable<CharSequence>   _numberChangeObservable = RxTextView.textChanges(_number).skip(1);  
 
  
 
Observable.combineLatest(_emailChangeObservable,  
 
              _passwordChangeObservable,  
 
              _numberChangeObservable,  
 
              new Func3<CharSequence, CharSequence, CharSequence, Boolean>() {  
 
                  @Override  
 
                  public Boolean call(CharSequence newEmail,  
 
                                      CharSequence newPassword,  
 
                                      CharSequence newNumber) {  
 
  
 
                      Log.d("xiayong",newEmail+" "+newPassword+" "+newNumber);  
 
                      boolean emailValid = !isEmpty(newEmail) &&  
 
                                           EMAIL_ADDRESS.matcher(newEmail).matches();  
 
                      if (!emailValid) {  
 
                          _email.setError("Invalid Email!");  
 
                      }  
 
  
 
                      boolean passValid = !isEmpty(newPassword) && newPassword.length() > 8;  
 
                      if (!passValid) {  
 
                          _password.setError("Invalid Password!");  
 
                      }  
 
  
 
                      boolean numValid = !isEmpty(newNumber);  
 
                      if (numValid) {  
 
                          int num = Integer.parseInt(newNumber.toString());  
 
                          numValid = num > 0 && num <= 100;  
 
                      }  
 
                      if (!numValid) {  
 
                          _number.setError("Invalid Number!");  
 
                      }  
 
  
 
                      return emailValid && passValid && numValid;  
 
  
 
                  }  
 
              })//  
 
              .subscribe(new Observer<Boolean>() {  
 
                  @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合并两个数据源。例如一组数据来自网络,一组数据来自文件,需要合并两组数据一起展示。
 
 
  
  
   
   
    
    [html] 
    
    view plain
    
    copy
    
    
   
   
  
  
  
  
Observable.merge(getDataFromFile(), getDataFromNet())  
 
              .observeOn(AndroidSchedulers.mainThread())  
 
              .subscribe(new Subscriber<String>() {  
 
                  @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中是否存在数据,任何一步一旦发现数据后面的操作都不执行。


[html]  view plain copy


1. Observable<String> memory = Observable.create(new Observable.OnSubscribe<String>() {  
2.     @Override  
3. <? 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. <? super String> subscriber) {  
14. 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. <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. <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. <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. <? 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. <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. <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. > NetworkService.getMessage(s))  
      3. > {  
      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());