原文链接 http://blog.csdn.net/theone10211024/article/details/50435325
一、Scheduler线程切换
这种场景经常会在“后台线程取数据,主线程展示”的模式中看见
[html]view plaincopy
Observable.just(1, 2, 3, 4)
.subscribeOn(Schedulers.io()) // 指定 subscribe() 发生在 IO 线程
.observeOn(AndroidSchedulers.mainThread()) // 指定 Subscriber 的回调发生在主线程
.subscribe(new Action1() {
@Override
public void call(Integer number) {
Log.d(tag, "number:" + number);
}
});
二、使用debounce做textSearch
用简单的话讲就是当N个结点发生的时间太靠近(即发生的时间差小于设定的值T),debounce就会自动过滤掉前N-1个结点。
比如在做百度地址联想的时候,可以使用debounce减少频繁的网络请求。避免每输入(删除)一个字就做一次联想
[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结合RxJava做网络请求框架
这里不作详解,具体的介绍可以看扔物线的这篇文章,对RxJava的入门者有很大的启发。其中也讲到了RxJava和Retrofit如何结合来实现更简洁的代码
四、RxJava代替EventBus进行数据传递:RxBus
注意:RxBus并不是一个库,而是一种模式,是使用了RxJava的思想来达到EventBus的数据传递效果。这篇文章把RxBus讲的比较详细。
例如:注册的时候所有输入信息(邮箱、密码、电话号码等)合法才点亮注册按钮。
[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合并两个数据源。
例如一组数据来自网络,一组数据来自文件,需要合并两组数据一起展示。
[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中是否存在数据,任何一步一旦发现数据后面的操作都不执行。
[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做定时操作。当有“x秒后执行y操作”类似的需求的时候,想到使用timer
例如:2秒后输出日志“hello world”,然后结束。
[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做周期性操作。当有“每隔xx秒后执行yy操作”类似的需求的时候,想到使用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防止按钮重复点击
ps:debounce也能达到同样的效果
[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做轮询请求
[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进行数组、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);
}
});
十三、解决嵌套回调(callback hell)问题
[html]view plaincopy
NetworkService.getToken("username", "password")
.flatMap(s ->NetworkService.getMessage(s))
.subscribe(s ->{
System.out.println("message: " + s);
})
十四、响应式的界面
比如勾选了某个checkbox,自动更新对应的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());
最后,由于个人能力有限,文章难免有疏漏之处,如果您有任何疑议,请让我知道,谢谢!本文所有的例子已经上传到github上