Retrofit和RxJava系列博客:
使用Retrofit上传文件
使用Gson解析Retrofit返回结果
Retrofit和RxJava结合使用
使用Retrofit和RxJava进行轮询操作
根据前面几篇博客,已经大致明白了Retrofit和RxJava的使用。现在把这些知识结合起来,实现一个轮询操作。
轮询流程
轮询的过程是:先查询userId,得到userId以后上传图片,如果图片上传成功,客户端就开始轮询服务器。轮询每隔10s进行一次,总共轮询5次,如果服务器返回1或者-1则轮询截止。这个流程如下图所示:
RxJava中的相关运算符
- interval
每隔一段时间发送一个数据,用于轮询的时间间隔控制 - take
限制通过的数据流的数量,用来限制轮询次数 - flatMap
进行数据的变换 - takeUntil
设置通过的条件,一旦满足条件就停止发送,这里用于设定轮询结束的条件 - filter
对通过的数据进行过滤,用于控制数据流,处理判断语句
主要流程实现
new QueryUserInfo("22", "502").startQuery()
.subscribeOn(Schedulers.io())
.flatMap(userJsonResult -> new UpLoadImage("1218", "/storage/sdcard/Desert.jpg").upload())
.filter(uploadJsonResult1 -> uploadJsonResult1.getFlag().equals("1"))
.flatMap(uploadJsonResult2 -> new Polling("1218").startPolling())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(pollingJsonResult -> Log.d("polling result", pollingJsonResult.getMessage()));
首先,new QueryUserInfo("22", "502").startQuery()
获取userId,然后使用flatMap(userJsonResult -> new UpLoadImage("1218", "/storage/sdcard/Desert.jpg").upload())
上传图片,filter(uploadJsonResult1 -> uploadJsonResult1.getFlag().equals("1"))
表示如果图片上传成功则继续进行,随后的flatMap(uploadJsonResult2 -> new Polling("1218").startPolling())
表示开始轮询操作。subscribeOn(Schedulers.io())
表示网络请求是在Schedulers.io()
线程中进行。
轮询
这个例子的核心在于轮询的编写。使用RxJava的轮询需要组合多个运算符:
Observable.interval(10, TimeUnit.SECONDS)
.take(5)
.observeOn(Schedulers.io())
.flatMap(aLong -> service.polling(userId))
.takeUntil(pollingJsonResult -> pollingJsonResult.getResult().equals("1") || pollingJsonResult.getResult().equals("-1"));
Observable.interval(10, TimeUnit.SECONDS)
表示每隔10s发出一次请求,take(5)
表示只取前5个,flatMap(aLong -> service.polling(userId))
即进行一次服务器访问,takeUntil
表明满足后面条件就停止请求。
结果
轮询操作结果如下:
userId: 1218
userId: 1244
upload image: 发送成功!
Polling: start polling
polling result: 主人很忙,请等待。。。。!
polling result: 主人很忙,请等待。。。。!
polling result: 主人很忙,请等待。。。。!
polling result: 主人很忙,请等待。。。。!
polling result: 主人很忙,请等待。。。。!
从这个例子可以看到,使用RxJava进行轮询操作时,代码是比较简洁的,上手的难点在于多种操作符的组合使用。RxJava的操作符繁多,在使用之前最好进行试验验证,只有在实践中多多练习才能真正熟练使用。此外,官方文档也是重要的学习资料,可以先阅读官方文档的操作符说明,然后试验后应用。