未来已来|人工智能与数据库融合发展分论坛议程初探 了解详情
写点什么

从案例学 RxAndroid 开发(下)

  • 2016-04-07
  • 本文字数:2936 字

    阅读完需:约 10 分钟

6 月 17 日,极客时间《企业级 Agents 开发实战营》正式上线,10 周掌握企业级 Agents 从设计、开发到部署全流程。

欢迎回来!看来你想更多的了解 RxJava。如果你还没有看第一部分 (此处链接有待修改),推荐先看第一篇。现在我们来看其他几个例子。再说一遍,所有的例子都可以在这个 repo 里找到。在每个例子的开始,我都会说明代码是属于哪个 Activity 的。 案例 4:Subjects

现在我们写一个 Activity ,里面要展示一个数字并有一个自增按钮。在看代码之前,先介绍另一个有关 RxJava 的概念,Subject。Subject 这个对象既是 Observable 又是 Observer,我会把 Subject 想象成一个管道:从一端把数据注入,结果就会从另一端输出。

Subject 有好几类,在这里我们使用最简单的:PublishSubject。使用 PublishSubject 时,一旦数据从一端注入,结果会立即从另一端输出。

首先我们要写这个管道的输出端。刚才说了 Subject 也是 Observable,也就是说我们可以像观察任何一个 Observable 一样观察它。这段代码的功能就是观察管道的输出端到底输出了什么。我们在这里写一个很简单的 Observer 来更新 mCounterDisplay 控件。

复制代码
mCounterEmitter = PublishSubject.create();
mCounterEmitter.subscribe(new Observer<Integer>() {
@Override
public void onCompleted() { }
@Override
public void onError(Throwable e) { }
@Override
public void onNext(Integer integer) {
mCounterDisplay.setText(String.valueOf(integer));
}
});

与第一部分中的例子不同,在这个例子中 onNext() 会被调用多次。每次发送新的数据时,mCounterDisplay 都会展示新的数据。但是 PublishSubject 怎么发送数据呢?让我们看一下 mIncrementButton 的监听代码。

复制代码
mIncrementButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mCounter++;
mCounterEmitter.onNext(mCounter);
}
});

可以看到 mIncrementButton 在 onClick() 回调方法中做了两件事情:

  1. 让 mCounter 变量自增。
  2. 调用 mCounterEmitter 的 onNext() 方法并传入 mCounter。

由于 Subject 同时也是 Observer,所以它也有 onNext() 方法,因此我们可以通过调用 onNext() 方法把数据注入管道的输入端,可以理解为同我们在一端中观察自增按钮是否被点击,然后把信息告知管道另一端的 Observer。 案例 5:Map()

我们现在要写一个只显示一个数字的 Activity 。这将是一个很简单的 Activity,因为我们要在这里使用 map 方法。如果你接触过函数式编程,你可能对 map 并不陌生。你可以把 map 当做一个方法,它接收一个数据,然后输出另一个数据,当然输入输出的两个数据之间是有联系的。

我们先写一个只发送一个数字 4 的 Single 对象。

复制代码
Single.just(4).map(new Func1<Integer, String>() {
@Override
public String call(Integer integer) {
return String.valueOf(integer);
}
}).subscribe(new SingleSubscriber<String>() {
@Override
public void onSuccess(String value) {
mValueDisplay.setText(value);
}
@Override
public void onError(Throwable error) { }
});

我们最终要显示 Single 所发送的数据,但首先我们需要将这个数据从 Integer 转为 String,而这里的解决方法就是使用 map() 函数。正如刚才所说,map 接收一个数据,进行处理而后输出它,这正是我们需要的。现在 Single 会发送数字 4,我们使用 map() 方法将其转为 String,而后交给 Observer 去展示它。

这个例子中对于 map 方法的使用很轻量,不过 map 可是非常强大的,在下一个例子中你可以看到,map 可以被用来执行任意代码,在处理数据方面起到很重要的作用。 案例 6:综合使用

现在我们要写一个用来根据名字搜索城市的 Activity 。在这个 Activity 中,我们要使用在这两篇文章中所学的所有知识并写一个比较大的例子。同时还要介绍一个新的概念:deboundce。开始。

现在我们要写一个 PublishSubject,并能接收用书输入进输入框的数据,而后根据输入获取符合的列表,并展示。

复制代码
mTextWatchSubscription = mSearchResultsSubject
.debounce(400, TimeUnit.MILLISECONDS)
.observeOn(Schedulers.io())
.map(new Func1<String, List<String>>() {
@Override
public List<String> call(String s) {
return mRestClient.searchForCity(s);
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<List<String>>() {
@Override
public void onCompleted() { }
@Override
public void onError(Throwable e) { }
@Override
public void onNext(List<String> cities) {
handleSearchResults(cities);
}
});
mSearchInput.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
mSearchResultsSubject.onNext(s.toString());
}
@Override
public void afterTextChanged(Editable s) { }
});

这段代码有不少内容,让我们一点一点分析。

首先你会看到 debounce() 方法。这是啥?有啥用?如果你看一下我们是如何给输入框添加监听器的,你会发现每当输入的内容改变时都会有输入发送到 mSearchResultsSubject,不过我们不想让用户每点一个键都向服务器请求一次。我们想等一会,等用户停止输入(代表差不多输完)的时候再请求服务器。

而 debounce() 方法就是做这个的。这个方法告诉 mSearchResultsSubject 在没有数据传入达 400 毫秒时才发送数据。意思就是,仅当用户 400ms 都没有改变输入内容时,Subject 才会发送最新的搜索字符串。这样以来我们就不会进行无意义的网络请求了,UI 也不会每输入一个字符都更新。

我们想通过 RestClient 来访问服务器,而因为 RestClient 涉及 IO 操作,我们需要在 IO Scheduler 中进行这个操作,所以要写 observeOn(Schedulers.io())。

好了,现在我们会把搜索字段发送到 IO Scheduler 中,在这里 map 就要发挥作用了,我们在 map 方法中通过关键字获取搜索结果的列表。在 map 中我们可以调用任意外部方法,在这里使用 RestClient 获取搜索结果。

因为 map 方法会在 IO Scheduler 中运行,而我们又要用其返回值填充 View,所以要重新切换到 UI 线程,所以要写 observeOn(AndroidSchedulers.mainThread())。现在搜索结果会被发送到 UI 线程。要注意两个 observeOn() 方法的顺序,这一点至关重要。现在我们总结一下数据发送的顺序。

复制代码
mSearchResultsSubject
|
|
V
debounce
|||
|||
V
map
|
|
V
observer

一个竖杠代表数据在 UI 线程中发送,三个竖杠代表数据在 IO Scheduler 中发送。

最终,我们获得搜索结果,并展示给用户。 结语

有关 RxJava 就说这么多了,希望这两篇文章能帮你了解 RxJava 的基础。强烈建议你自己探索有关 RxJava 的其他方面。如果你有问题或者只是想说点什么,欢迎在下方留言。

2016-04-07 17:243807

评论

发布
暂无评论
发现更多内容

探究Presto SQL引擎(4)-统计计数

vivo互联网技术

浏览器 presto 引擎

京东云开发者|提高IT运维效率,深度解读京东云AIOps落地实践

京东科技开发者

人工智能 异常检测 时序架构 运维‘

面试官:请实现Javascript发布-订阅模式

helloworld1024fd

JavaScript

RocketMQ Flink Catalog 设计与实践

晓双

flink Apache RocketMQ catalog

基于BPMN2.0的业务流程引擎

GFE

前端 BPMN 流程引擎

Wallys/Qualcomm IPQ5018 solution application wifi6 , support M.2 Card Slot for QCN9074 WIFI 6E Card

Cindy-wallys

802.11AX WIFI 6e ipq5018

“鸿蒙生态专家面对面”技术交流会,专家齐聚,等你前来!

HarmonyOS开发者

HarmonyOS

Wallys//IPQ8072/IPQ8074/IPQ8072A/IPQ8074A/HighPower 802.11ax SoC for Routers, Gateways and Access Points

Cindy-wallys

802.11AX IPQ8072 IPQ8074 HighPower

11月月更开启啦!冬天到了,不写点东西暖暖身子吗?

InfoQ写作社区官方

热门活动 11月月更

前端高频手写题自测,你能做出几道

helloworld1024fd

JavaScript

案例解读华为隐私计算产品TICS如何实现城市跨部门数据隐私计算

华为云开发者联盟

云计算 华为云 隐私计算 企业号十月 PK 榜

【C语言】前言关键字

謓泽

11月月更

基于qiankun的微服务落地实践

GFE

微服务 前端 qiankun

以开发之名 | 小红书:用年轻人的方式开发年轻人喜欢的应用

HMS Core

视频超分 小红书

深度理解Redux原理并实现一个redux

夏天的味道123

React

公链defi质押挖矿分红dapp系统开发(合约定制)

开发微hkkf5566

应用实践:Paddle分类模型大集成者[PaddleHub、Finetune、prompt]

汀丶人工智能

nlp 文本分类 关系抽取 命名实体识别 11月月更

爆肝整理高频js手写题请查收

helloworld1024fd

JavaScript

珠宝加工厂:我的成本下降空间在哪里

华为云开发者联盟

云计算 物联网 华为云 企业号十月 PK 榜

没想到GoFrame的gcache天然支持缓存淘汰策略

王中阳Go

Go golang 高效工作 学习方法 11月月更

币安DAPP系统开发技术概念及篡改逻辑

I8O28578624

Docker不香吗?为什么还要用k8s

源字节1号

微信小程序 软件开发 前端开发 后端开发

云小课|MRS基础原理之MapReduce介绍

华为云开发者联盟

大数据 华为云 企业号十月 PK 榜

计算机网络:电路、报文与分组交换

timerring

计算机网络 11月月更

深度讲解React Props

夏天的味道123

React

PaddleBox:百度基于GPU的超大规模离散DNN模型训练解决方案

百度Geek说

企业号十月 PK 榜 PaddlePaddl 模型训练框架 大规模离散模型

关于“React 和 Vue 该用哪个”我真的栓Q

京东科技开发者

Vue 前端 Vue 3 VUE 3.0 源码 react rout

探索行为可回溯系统的应用与实现

GFE

前端 监控

量化合约系统开发逻辑篡改方案

I8O28578624

用git上传项目到GitHub或者码云全过程

肥晨

代码上传 githun 11月月更 Git上传

高频js手写题之实现数组扁平化、深拷贝、总线模式

helloworld1024fd

JavaScript

从案例学RxAndroid开发(下)_Java_Kurtis Nusbaum_InfoQ精选文章