简单介绍一下业务逻辑:获取字符串,如果获取失败进行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 : 123:33:14.908 32364-32377/? D/LogUtils: execute getMsg count : 223:33:14.908 32364-32377/? D/LogUtils: execute getMsg count : 323:33:14.909 32364-32377/? D/LogUtils: execute getMsg count : 423:33:14.909 32364-32377/? D/LogUtils: execute getMsg count : 523:33:14.909 32364-32377/? D/LogUtils: execute getMsg count : 623:33:14.909 32364-32377/? D/LogUtils: execute getMsg count : 723:33:14.909 32364-32377/? D/LogUtils: execute getMsg count : 823:33:14.909 32364-32377/? D/LogUtils: execute getMsg count : 923:33:14.909 32364-32377/? D/LogUtils: execute getMsg count : 1023:33:14.909 32364-32377/? D/LogUtils: result : null
针对上述业务逻辑改为RxJava实现,使用操作符retry
可实现
代码块
public void testMain() { getSyncMsg().subscribe(getSubscriber()); } private ObservablegetSyncMsg() { MsgTool msgTool = new MsgTool(); Observable o = Observable.create(subscriber -> { try { subscriber.onNext(msgTool.getMsg()); subscriber.onCompleted(); } catch (Exception e) { subscriber.onError(e); } }); return o.retry(10); } private Subscriber
输出结果
23:45:43.761 3285-3307/? D/LogUtils: execute getMsg count : 123:45:43.762 3285-3307/? D/LogUtils: execute getMsg count : 223:45:43.763 3285-3307/? D/LogUtils: execute getMsg count : 323:45:43.763 3285-3307/? D/LogUtils: execute getMsg count : 423:45:43.763 3285-3307/? D/LogUtils: execute getMsg count : 523:45:43.763 3285-3307/? D/LogUtils: execute getMsg count : 623:45:43.763 3285-3307/? D/LogUtils: execute getMsg count : 723:45:43.763 3285-3307/? D/LogUtils: execute getMsg count : 823:45:43.764 3285-3307/? D/LogUtils: execute getMsg count : 923:45:43.764 3285-3307/? D/LogUtils: execute getMsg count : 1023:45:43.764 3285-3307/? D/LogUtils: execute getMsg count : 1123:45:43.765 3285-3307/? D/LogUtils: onError : java.lang.Exception: exception getMsg
下面我们增加一个业务逻辑,每次重试延迟一秒种。此功能不做Java代码实现(使用定时器、Android系统下使用Handler等),而用RxJava代码实现,虽然看着很迷糊,但是慢慢品味就会发觉它的魅力所在。
public void testMain() { getSyncMsg().subscribe(getSubscriber()); } private ObservablegetSyncMsg() { MsgTool msg = new MsgTool(); Observable o = Observable.create(subscriber -> { try { subscriber.onNext(msg.getMsg()); subscriber.onCompleted(); } catch (Exception e) { subscriber.onError(e); } }); return o.retryWhen(this::delayRetry); } //此方法就是魅力的所在 private Observable delayRetry(Observable 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 getSubscriber() { return new Subscriber () { @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: onStart00:36:57.297 19355-19372/? D/LogUtils: execute getMsg count : 100:36:58.305 19355-19377/? D/LogUtils: execute getMsg count : 200:36:59.306 19355-19404/? D/LogUtils: execute getMsg count : 300:37:00.307 19355-19375/? D/LogUtils: execute getMsg count : 400:37:01.308 19355-19376/? D/LogUtils: execute getMsg count : 500:37:02.308 19355-19377/? D/LogUtils: execute getMsg count : 600:37:03.309 19355-19404/? D/LogUtils: execute getMsg count : 700:37:04.309 19355-19375/? D/LogUtils: execute getMsg count : 800:37:05.310 19355-19376/? D/LogUtils: execute getMsg count : 900:37:06.311 19355-19377/? D/LogUtils: execute getMsg count : 1000:37:06.320 19355-19377/? D/LogUtils: onError : java.lang.Exception: exception getMsg