java if or android_RxJava switchIfEmpty操作符实现Android检查本地缓存逻辑判断

switchIfEmpty(Observable emptyObservable)操作符从字面意思上就很好理解,就是当为空的时候跳转到emptyObservable。

那末如何理解当为空的时候. 下面将会使用实际案例解释这个switchIfEmpty的使用方法。

业务需求

假设我们的app里有加载文章列表功能,要求加载的逻辑以下:加载文章的的时候,先从本地加载,如果本地存在就是用本地的数据,如果不存在从网络获得。

下面是业务代码:

//从本地数据获得文章列表

getArticlesObservable(pageIndex, pageSize, categoryId)

//本地不存在,要求api

.switchIfEmpty(articleApi.getArticlesByCategoryId(pageIndex + "", pageSize + "", categoryId + "")

.compose(this.handlerResult())

.flatMap(new Func1>() {

@Override

public Observable call(RespArticlePaginate respArticlePaginate) {

if (respArticlePaginate != null && respArticlePaginate.getList() != null) {

try {

articleDao.insertOrReplaceInTx(respArticlePaginate.getList());

} catch (Exception e) {

e.printStackTrace();

}

}

return Observable.just(respArticlePaginate);

}

}))

.subscribeOn(Schedulers.io())

.observeOn(AndroidSchedulers.mainThread())

.subscribe(createSubscriber(ID_ARTICLE_LIST)))

这里的 createSubscriber 封装了Subscriber对成功、失败的数据处理,然后统1把数据推给上1层,就不用每一个地方都写下面相同的模板代码了:

observable.subscribe(new Action1() {

@Override

public void call(RespArticlePaginate respArticlePaginate) {

//success data

}

}, new Action1() {

@Override

public void call(Throwable throwable) {

// error data

}

})

那末createSubscriber是如何实现的,先看subscribe方法源码 以下:

public final Subscription subscribe(final Action1 super T> onNext, final Action1 onError) {

if (onNext == null) {

throw new IllegalArgumentException("onNext can not be null");

}

if (onError == null) {

throw new IllegalArgumentException("onError can not be null");

}

Action0 onCompleted = Actions.empty();

return subscribe(new ActionSubscriber(onNext, onError, onCompleted));

}

很简单,他是直接new了1个ActionSubscriber,然后把我们之前在代码里写的各个回调(onNext、onError、onComplete)当作参数传递进去。那末我们的createSubscriber也能够摹拟它的实现:

/**

* 处理结果(分发结果) 封装

*

*@param id 辨别业务类型

*/

protected ActionSubscriber createSubscriber(final int id) {

//由于我们只关心onNext和onError

Action0 onCompleted = Actions.empty();

return new ActionSubscriber(new Action1() {

@Override

public void call(T t) {

pushSuccessData(id, t);

}

}, new Action1() {

@Override

public void call(Throwable throwable) {

pushThrowable(id, throwable);

}

}, onCompleted);

}

好了,言归正传,回到我们上面提到的需求。根据需求我们来分析下代码:

getArticlesObservable方法用来从本地获得文章列表,articleApi.getArticlesByCategoryId方法是用来当本地不存在的时候从网络获得。仿佛这些代码可以实现了我们上面提到的需求了。而且很简洁。

实践是检验真谛的唯1标准,我们先运行下看看(本地环境是数据库没有文章列表)。

运行后,发现界面并没有展现数据,通过debug返现,代码履行了检测本地缓存的逻辑,且本地找不到符合逻辑的数据,也就是说从本地找到的结果为空。但是没有依照我们料想的是履行网络要求。

先来看看查询本地缓存的代码是是甚么模样。

Observable.create(new Observable.OnSubscribe() {

@Override

public void call(Subscriber super Object> subscriber) {

try {

List as = articleDao.queryBuilder()

.where(ArticleDao.Properties.CategoryId.eq(categoryId))

.orderDesc(ArticleDao.Properties.Id)

.offset((pageIndex - 1) * pageSize)

.limit(pageSize).list();

if (as == null || as.isEmpty()) {

subscriber.onNext(null);

}else{

subscriber.onNext(as);

}

}catch (Exception e){

subscriber.onError(e);

}

subscriber.onCompleted();

}

});

通过debug发现代码走的逻辑是

if (as == null || as.isEmpty()) {

subscriber.onNext(null);

}

发送的是空,为何还是没有走switchIfEmpty里的逻辑呢?肯定是我们用的姿式不对,先看看该该方法的说明:

/**

* Returns an Observable that emits the items emitted by the source Observable or the items of an alternate

* Observable if the source Observable is empty.

*

*

*

Scheduler:

*

{@code switchIfEmpty} does not operate by default on a particular {@link Scheduler}.

*

*

* @param alternate

* the alternate Observable to subscribe to if the source does not emit any items

* @return an Observable that emits the items emitted by the source Observable or the items of an

* alternate Observable if the source Observable is empty.

* @since 1.1.0

*/

public final Observable switchIfEmpty(Observable extends T> alternate) {

return lift(new OperatorSwitchIfEmpty(alternate));

}

重点关注对参数Observable extends T> alternate的解释:

the alternate Observable to subscribe to if the source does not emit any items

意思是如果原来的Observable没有发射任何数据(emit any items),则使用alternate代替原来的Observable。

好,再看看我们的代码逻辑:

if (as == null || as.isEmpty()) {

subscriber.onNext(null);

}

这段代码不是没有发射数据,而是发射了个空数据,也就是发射了null,所以这段代码其实不是没有发射任何数据,所以为何不走网络要求的逻辑。

知道缘由就好解决了,加上个过滤就能够解决问题了:

.filter(new Func1() {

@Override

public Boolean call(RespArticlePaginate respArticlePaginate) {

return respArticlePaginate != null;

}

})

总结

1,通过switchIfEmpty可以做到1些逻辑判断,固然实现类型的判断本地缓存的,可以通过concat结合takeFirst操作符来实现,具体的可以看我之前的博客文章

2,上面通过Observable.create方式来包装数据查询,不是很优雅。下1篇博客介绍如何封装RxJava,使得我们的代码支持RxJava链式调用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/302811.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

这是对R的误解!R的应用原来这么广!

R作为一种统计分析软件,广泛应用于生物、医学、电商、新闻等数据相关行业,是目前主流数据应用软件之一。为了更好地帮助大家了解并快速入门R语言,现超级数学建模携手柯老师以R语言为基础,向大家隆重推出《R语言基础》系列课。柯老…

WinDBg定位asp.net mvc项目异常崩溃源码位置

项目介绍:asp.net mvc angular iiswindows server系统莫名崩溃最近有个系统默认奇妙崩溃50x,服务整体变成无响应,当运维告知我只有重启应用程序池项目才能正常。我问他如何重现,得到的回复是我这里无法重现,但客户使用…

selenium webdirver之ruby-开发ide安装

这里用到的ide是netbeans ruby环境安装好后,下载netbeans,然后进行安装 netbeans ruby plugins download URL:http://jruby.org.s3.amazonaws.com/downloads/community-ruby/community-ruby_7_1_preview1.zip 解压 打开netbeans,工…

mysql如何和qt连接使用_Qt5学习:连接MySQL数据库

一、环境QT版本:QT 5.8.0(msvc2013_64)MySQL版本:mysql 5.7.19二、配置之前 mysql 数据库一直都连接不上,网上也搜了很多资料,主要还是库文件的问题。重新将 mysql.pro 编译一下,将生成的 .dll 和 .lib 文件拷贝到 QT …

TensorFlow框架的这些操作你肯定不知道!

谷歌在上周正式推出了深度学习框架TensorFlow 1.11.0 版本,那么TensorFlow框架到底是什么?TensorFlow™ 是一个采用数据流图(data flow graphs),用于数值计算的开源软件库。最初由Google大脑小组的研究员和工程师们开发…

C#中HashTable、Dictionary、ConcurrentDictionary区别

一、HashTableHashTable表示键/值对的集合。在.NET Framework中,Hashtable是System.Collections命名空间提供的一个容器,用于处理和表现类似key-value的键值对,其中key通常可用来快速查找,同时key是区分大小写;value用…

CDA数据分析师备考必看,L1L2通用

CDA数据分析师L1,L2均可 可安排当月月底的线上考试 线上考的为双机位监考,但是不用担心 安全无隐患,需要联系 当月拿证

[SIR数据集实验][2]Java类数据集相应工具使用的小经验

这段时间安排一个师弟在继续学习SIR数据集的使用和实验方法,这里我先总结点经验。 如果要生成某一个数据集的Fault Matrix,(虽然一般在info目录下有已经生成好的Fault Matrix,但按照Java Object Handbook里面的建议,最…

java 异步读写_Java异步与AIO

异步编程提供了一个非阻塞的,事件驱动的编程模型。 这种编程模型利用系统中多核执行任务来提供并行,因此提高了应用的吞吐率。Java异步编程通常需要使用Future,FutureTask和Callable,其中Future代表未来的某个结果,一般…

你以为妹子穿短裙真的是为了诱惑你吗?

全世界有3.14 % 的人已经关注了数据与算法之美每年暑假,ChinaJoy 都会火热进行,无数一年不出家门的宅男们扛着“长枪大炮”,向着短裙姑娘们就冲过去了。关于裙子,林语堂曾有过一句名言:“演讲应该像女士的裙子&#xf…

聊一聊Jmeter的参数化

背景 前面一篇聊了一下 JMeter 的简单使用,这篇聊一下 JMeter 的参数化。在开始之前先来一个单元测试的例子,感受一下参数化。上面是一个用 xUnit 写的单元测试,这个单元测试就是一个参数化的例子:模拟了不同的输入,调…

Android VNC Server New

Android VNC Server New 关于VNC请参见维基百科:http://zh.wikipedia.org/wiki/VNC关于执行Android VNC Server,请参见前一篇文章:点击链接 一、VNC下载1)fastdroid-vncAndroid VNC Server开源项目 http://code.google.com/p/fast…

python bind sock_python SOCKET编程详细介绍

本章内容1、socket2、IO多路复用3、socketserverSocketsocket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,对于文件用【打开】【读写】【关闭】模式来操作。socket就是该模式的一个实现,socket即是一种特殊的文件,一些…

EPPlus导出Excel感觉很不错~~~

前言导出成为很多系统的必备功能,之前分享过导出PDF的功能,这里来分享一下Excel的导出;提到Excel导出,NPOI肯定是很多小伙伴的首选,在以往的项目中也用其完成了很多导出需求;对于NPOI,个人感觉使…

[文摘]标准的软件开发过程

为什么80%的码农都做不了架构师?>>> 软件开发的标准过程包括六个阶段,而六个阶段需要编写的各类文件达 14 种之多,在每个阶段需要编写哪些文件,以及这些文件的主要内容见下: 1.可行性与计划研究阶段 可行性…

python新闻评论分析_从新闻文章中提取评论

我的问题和这里问的问题类似:https://stackoverflow.com/questions/14599485/news-website-comment-analysis我试图从任何新闻文章中摘录评论。E、 g.我有一个新闻网址:http://www.cnn.com/2013/09/24/politics/un-obama-foreign-policy/我尝试在python中…

走进乔布斯的大脑

全世界有3.14 % 的人已经关注了数据与算法之美你永远也无法走进苹果教父乔布斯神秘的大脑,但下面的图可以让你多靠近了解他一点。人们都想走进乔帮主的大脑里看看他的想法,可惜他太难以捉摸了。但是,有个有趣的方法,至少可以让人们…

如何在没有 System.Drawing.Common 的情况下使用 C# 获取图片格式

之前写过一篇博文,用来获取图片的正确格式。博文所示代码一直工作良好,直到今天在将程序部署到阿里云函数计算时,发生了以下报错:System.Drawing is not supported on this platform.这表明我们不能在阿里云函数计算服务器上使用 …

Ant通配符

我们常用的匹配模式有ANT模式,比如acegi可以用PATTERN_TYPE_APACHE_ANT来使用ANT匹配模式,那什么是ANT匹配模式呢。ANT通配符有三种:通配符 说明 ? 匹配任何单字符 * 匹配0或者任意数量的字符 ** 匹配0或者更多的目录 例子:UR…

java二叉树的深度优先遍历_二叉树的广度优先遍历、深度优先遍历的递归和非递归实现方式...

1 packageSolution;23 importjava.util.LinkedList;4 importjava.util.Queue;5 importjava.util.Stack;678 public classBinaryTree {910 //二叉树节点11 public static classBinaryTreeNode {12 intvalue;13 BinaryTreeNode left;14 BinaryTreeNode right;1516 public BinaryT…