RxJava使用场景搜集

时间:2022-02-10 17:47:22

RxJava使用场景搜集

RxJava从多个数据源获取数据

传送门

Observable<Bitmap> memory=...;
Observable<Bitmap> disk=...;
Observable<Bitmap> network=...;

Observable source = Observable.concat(memory,disk,metwork).first(new Func1<Bitmap, Boolean>() {
@Override
public Boolean call(Bitmap bitmap) {
return null!=bitmap;
}
});

first()和takeFirst()操作符的比较

对于这种设计模式,first()和takeFirst()操作符可以二选其一。
两种调用方式的区别在于,如果所有数据源的数据均过期,没有任何的有效数据作为事件发送,first()会抛出NoSuchElementException异常(译者注:first()操作符均 return false),而takeFirst()操作符则直接调用完成操作,不会抛出任何异常。

使用RxJava实现延迟订阅

传送门

创建Observable的操作符
just,from这类创建Observable的操作符比如在创建之初,就已经存储了对象的值,而不是被订阅的时候才赋值。
使用defer()操作符,使代码直到被订阅才会被执行。

String value = "hello";
Observable.defer(new Func0<Observable<String>>() {
@Override
public Observable<String> call() {
return Observable.just(value);
}
});

defer()缺点

每次订阅都会创建一个新的Observable对象。  

线程切换

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

Schedulers.io() //运行至子线程(用于 I/O 操作)
Schedulers.computation() //运行至子线程(计算工作)
Schedulers.newThread() //运行至子线程(为任务创建的新线程)
AndroidSchedulers.mainThread() //运行至主线程 需添加compile ‘io.reactivex:rxandroid:1.0.1’

使用debounce做textSearch

用简单的话讲就是当N个结点发生的时间太靠近(即发生的时间差小于设定的值T),debounce就会自动过滤掉前N-1个结点。
比如在做百度地址联想的时候,可以使用debounce减少频繁的网络请求。避免每输入(删除)一个字就做一次联想

 .debounce(400, TimeUnit.MILLISECONDS)  

使用combineLatest合并最近N个结点

当两个Observables中的任何一个发射了一个数据时,通过一个指定的函数组合每个Observable发射的最新数据(一共两个数据),然后发射这个函数的结果

例如:注册的时候所有输入信息(邮箱、密码、电话号码等)合法才点亮注册按钮。

Observable<CharSequence> _emailChangeObservable = RxTextView.textChanges(_email).skip(1);  //skip 跳过前面的若干项数据
Observable<CharSequence> _passwordChangeObservable = RxTextView.textChanges(_password).skip(1);
Observable<CharSequence> _numberChangeObservable = RxTextView.textChanges(_number).skip(1);

Observable.combineLatest(_emailChangeObservable, _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);
}
});

使用interval做周期性操作。当有“每隔xx秒后执行yy操作”类似的需求的时候,想到使用interval

例如:每隔2秒输出日志“helloworld”。

Observable.interval(2, TimeUnit.SECONDS)  
.subscribe(new Observer<Long>() {
@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");
}
});

传送门

RxJava结合Retrofit

传送门