简单介绍一下业务逻辑:获取字符串,如果获取失败进行10次重试,超出10次未成功视为失败。

模拟获取字符串场景

代码块

   class MsgTool {
int count;
String getMsg() throws Exception {
count++;
LogUtils.d("execute getMsg count : " + count);
if (count == 15) {
return "getMsg";
} else {
throw new Exception("exception getMsg");
}
}
}

Java代码实现逻辑(实现方式很多种,这里不是重点)

代码块

    public void testMain() {
LogUtils.d("result : " + getSyncMsg());
} private String getSyncMsg() {
MsgTool msgTool = new MsgTool();
String result = null;
boolean isSuccess = false;
int count = 0;
while ((count < 10) && !isSuccess) {
try {
result = msgTool.getMsg();
isSuccess = true;
} catch (Exception e) {
count++;
}
}
return result;
}

输出结果

23:33:14.908 32364-32377/? D/LogUtils: execute getMsg count : 1
23:33:14.908 32364-32377/? D/LogUtils: execute getMsg count : 2
23:33:14.908 32364-32377/? D/LogUtils: execute getMsg count : 3
23:33:14.909 32364-32377/? D/LogUtils: execute getMsg count : 4
23:33:14.909 32364-32377/? D/LogUtils: execute getMsg count : 5
23:33:14.909 32364-32377/? D/LogUtils: execute getMsg count : 6
23:33:14.909 32364-32377/? D/LogUtils: execute getMsg count : 7
23:33:14.909 32364-32377/? D/LogUtils: execute getMsg count : 8
23:33:14.909 32364-32377/? D/LogUtils: execute getMsg count : 9
23:33:14.909 32364-32377/? D/LogUtils: execute getMsg count : 10
23:33:14.909 32364-32377/? D/LogUtils: result : null

针对上述业务逻辑改为RxJava实现,使用操作符retry可实现

代码块

    public void testMain() {
getSyncMsg().subscribe(getSubscriber());
} private Observable<String> getSyncMsg() {
MsgTool msgTool = new MsgTool();
Observable<String> o = Observable.create(subscriber -> {
try {
subscriber.onNext(msgTool.getMsg());
subscriber.onCompleted();
} catch (Exception e) {
subscriber.onError(e);
}
});
return o.retry(10);
} private Subscriber<Object> getSubscriber() {
return new Subscriber<Object>() {
@Override
public void onCompleted() {
LogUtils.d("onCompleted");
} @Override
public void onError(Throwable e) {
LogUtils.d("onError : " + e.toString());
} @Override
public void onNext(Object o) {
LogUtils.d("onNext : " + o);
}
};
}

输出结果

23:45:43.761 3285-3307/? D/LogUtils: execute getMsg count : 1
23:45:43.762 3285-3307/? D/LogUtils: execute getMsg count : 2
23:45:43.763 3285-3307/? D/LogUtils: execute getMsg count : 3
23:45:43.763 3285-3307/? D/LogUtils: execute getMsg count : 4
23:45:43.763 3285-3307/? D/LogUtils: execute getMsg count : 5
23:45:43.763 3285-3307/? D/LogUtils: execute getMsg count : 6
23:45:43.763 3285-3307/? D/LogUtils: execute getMsg count : 7
23:45:43.763 3285-3307/? D/LogUtils: execute getMsg count : 8
23:45:43.764 3285-3307/? D/LogUtils: execute getMsg count : 9
23:45:43.764 3285-3307/? D/LogUtils: execute getMsg count : 10
23:45:43.764 3285-3307/? D/LogUtils: execute getMsg count : 11
23:45:43.765 3285-3307/? D/LogUtils: onError : java.lang.Exception: exception getMsg

下面我们增加一个业务逻辑,每次重试延迟一秒种。此功能不做Java代码实现(使用定时器、Android系统下使用Handler等),而用RxJava代码实现,虽然看着很迷糊,但是慢慢品味就会发觉它的魅力所在。

    public void testMain() {
getSyncMsg().subscribe(getSubscriber());
} private Observable<String> getSyncMsg() {
MsgTool msg = new MsgTool();
Observable<String> o = Observable.create(subscriber -> {
try {
subscriber.onNext(msg.getMsg());
subscriber.onCompleted();
} catch (Exception e) {
subscriber.onError(e);
}
}); return o.retryWhen(this::delayRetry);
} //此方法就是魅力的所在
private Observable<Object> delayRetry(Observable<? extends Throwable> o) {
return o.zipWith(Observable.range(1, 10), //控制10次以内
(throwable, integer) -> {
if (integer == 10) { //如果是最后一次,结合的结果是异常。
return throwable;
} else {
return integer;
}
})
.flatMap(object -> Observable.create(subscriber -> {
//转换retryWhey发射的数据
if (object instanceof Throwable) {
subscriber.onError((Throwable) object);
} else {
subscriber.onNext(o);
subscriber.onCompleted();
}
}).delay(1, TimeUnit.SECONDS)); //延迟一秒发射
} private Subscriber<Object> getSubscriber() {
return new Subscriber<Object>() {
@Override
public void onCompleted() {
LogUtils.d("onCompleted");
} @Override
public void onError(Throwable e) {
LogUtils.d("onError : " + e.toString());
} @Override
public void onNext(Object o) {
LogUtils.d("onNext : " + o);
}
};
}

输出结果

00:36:57.271 19355-19372/? D/LogUtils: onStart
00:36:57.297 19355-19372/? D/LogUtils: execute getMsg count : 1
00:36:58.305 19355-19377/? D/LogUtils: execute getMsg count : 2
00:36:59.306 19355-19404/? D/LogUtils: execute getMsg count : 3
00:37:00.307 19355-19375/? D/LogUtils: execute getMsg count : 4
00:37:01.308 19355-19376/? D/LogUtils: execute getMsg count : 5
00:37:02.308 19355-19377/? D/LogUtils: execute getMsg count : 6
00:37:03.309 19355-19404/? D/LogUtils: execute getMsg count : 7
00:37:04.309 19355-19375/? D/LogUtils: execute getMsg count : 8
00:37:05.310 19355-19376/? D/LogUtils: execute getMsg count : 9
00:37:06.311 19355-19377/? D/LogUtils: execute getMsg count : 10
00:37:06.320 19355-19377/? D/LogUtils: onError : java.lang.Exception: exception getMsg

[RxJava^Android]项目经验分享 --- 失败重试的更多相关文章

  1. [RxJava^Android]项目经验分享 --- 异常方法处理

    简单介绍一下背景,最近RxJava很火,我也看来学习一下,计划在项目的独立模块中使用它.使用过程中遇到很多问题,在这里记录分享一下.可能有使用不当的地方,大家多多包涵.对于RxJava的基本概念和功能 ...

  2. [RxJava^Android]项目经验分享 --- RxLifecycle功能实现分析(一)

      最近在研究RxJava自定义操作符的实现原理,发现成型的项目案例较少.突然想起在项目中应用的RxLifecycle是使用自定义操作符,便拿来研究了一下.分析之前,跟大家了解一些相关操作符和RxLi ...

  3. [RxJava^Android]项目经验分享 --- RxLifecycle功能实现分析(二)

      接着上一篇文章的内容,这篇文章一边分析RxLifecycle的实现原理,一边学习RxJava操作符. 首先RxLifecycle在基础类里定义BehaviorSubject并绑定Activity或 ...

  4. [RxJava^Android]项目经验分享 --- 递归实现

    介绍一下业务逻辑:获取接口数据,根据接口内容判断是否需要继续获取数据. 本文使用递归思路,通过RxJava来实现此功能,获取数据的Observable直接用模拟的Observable.just()替代 ...

  5. 项目经验分享[转自min.jiang]

        最近三个月,我非常荣幸的做为TeamLeader带领几个小组成员做了一个国外项目,这里想为大家分享一些小经验,尽管我佣有六年多的项目经验,但我一直的方向是架构师.大家知道架构师一般情况是偏向技 ...

  6. Georgia Tech Online Master of Science in Computer Science 项目经验分享

    Georgia Tech Online Master of Science in Computer Science 项目经验分享 Posted on 2014/04/22 项目关键词:工科名校,计算机 ...

  7. IdentityServer4系列之中文文档及实际项目经验分享

    0.前言 原文:http://docs.identityserver.io/en/release/声明: 1.目录一至五章节根据IdentityServer英文文档翻译而来,有些内容会根据自己的理解来 ...

  8. Unity多媒体展示项目经验分享-ImageEffect+动态绑定

    Unity多媒体展示项目经验分享-ImageEffect+动态绑定+网络通信 <ignore_js_op> “海尔科技展墙”是去年年初我们为上海家电博览会制作的一个多媒体展项,有限的工期以 ...

  9. 使用Webpack+Gulp开发运行于Dcloud平台HTML5+引擎的混合APP项目经验分享

    什么是5+Runtime? 首先简单介绍一下5+Runtime: HTML5 Plus Runtime(5+Rumtime)是由Dcloud开发的一套"增强版的手机浏览器引擎",与 ...

随机推荐

  1. Android下LayoutInflater的使用

    在我们想XML布局文件转换为View对象的时候.我们都会使用LayoutInflate对象.顾名思义咋一眼就能看出来他是布局填充器.那么接下来看看LayoutInfalte的使用 总体分为 Layou ...

  2. CGAffineTransform

    这个是CoreGraphics框架中的CGAffineTransform类,可用于设定UIView的transform属性.控制视图的缩放.旋转和平移操作.另称仿射变换矩阵. Quartz转换实现原理 ...

  3. linux系统root用户忘记密码的重置方法

    如果不小心忘记了新安装的lCentOS7的root密码,现在将找回过程分享给大家. 1.首先,在启动grub菜单,选择编辑选项启动: 2.然后,按e 进入编辑模式: 3.将'linux 16'行'ro ...

  4. Swift3新特性汇总

    之前 Apple 在 WWDC 上已将 Swift 3 整合进了 Xcode 8 beta 中,而本月苹果发布了 Swift 3 的正式版.这也是自 2015 年底Apple开源Swift之后,首个发 ...

  5. RecyclerView解密篇(二)

    在上一篇(RecyclerView解密篇(一))文章中简单的介绍了RecyclerView的基本用法,接下来要来讲讲RecyclerView的更多用法,要实现不同的功能效果,大部分都还是在于Recyc ...

  6. STM32F412应用开发笔记之六:使用片上Flash存储参数

    我们的项目中需要保存一些系统配置参数,这些数据的特点是:数量少而且不需要经常修改,但又不能定义为常量,因为每台设备可能不一样而且在以后还有修改的可能.这就需要考虑这些参数保存的问题.将这类数据存在指定 ...

  7. CSS 中Font Awesome 图标(附码表)

    HTML中缩放的矢量图标,您可以使用CSS所提供的所有特性对它们进行更改,包括:大小.颜色.阴影或者其它任何支持的效果. Font Awesome 传送门:http://fontawesome.das ...

  8. 将plist文件读取成为数组

    NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"city" ofType:@"plist&q ...

  9. VS2012 集成 IL DASM IL微软中间语言查看器

    第一步: 找到IL DASM的安装位置,默认在C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools 第二步: ...

  10. 让IIS支持bootstrap 增加svg和woff格式文件的支持

    增加以下两种文件类型即可: .woff application/x-woff.svg image/svg+xml