[转载]RxJava使用场景

原文链接 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讲的比较详细。

五、使用combineLatest合并最近N个结点

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

[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上

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容