本文实例为大家分享了Retrofit2 RxJava2实现Android App自动更新,具体内容如下
为淮南等地区用户提供了全套网页设计制作服务,及淮南网站建设行业解决方案。主营业务为成都网站建设、网站设计、淮南网站设计,以传统方式定制建设网站,并提供域名空间备案等一条龙服务,秉承以专业、用心的态度为用户提供真诚的服务。我们深信只要达到每一位用户的要求,就会得到认可,从而选择与我们长期合作。这样,我们也可以走得更远!
功能解析
自动更新可以说已经是App的标配了,很多第三方平台也都支持这个功能,最近手头上的项目需要加入这个App自动更新,考虑到项目里有用到Retrofit2和RxJava2,于是打算使用它俩自己实现这个功能。
分析App自动更新,可以分为以下三个功能点:
1.APK文件的下载
2.下载进度的实时更新显示
3.下载完成后的自动安装
其中比较难的一点是下载进度的实时更新显示,更难的是如何优雅的进行下载进度的更新显示,这也是为什么我用Retrofit2和RxJva2实现的原因。
用过Retrofit的人都知道他的内部是基于OkHttp实现的,OkHttp大家可能都不陌生,本次解决如何优雅的进行下载进度的更新显示的关键就在OkHttp的拦截器中,拦截器可谓是OKHttp的一大精髓,通过拦截器我们可以拿到Http的请求和响应信息,拿到了这些,你想干什么都行了。本次解决问题的核心就是在拦截器中拿到下载内容的长度并通过自定义的RxBus发送事件将下载信息发送出去,然后在合适的地方拿到这些下载信息,通过Notification实时展示下载进度。
先上一张App自动更新的流程图

功能实现
首先根据功能需求我创建了七个类:
1.ApiManager(Retrofit初始化和Api接口定义)
2.ApkLoadingBean(下载长度和文件总长度的数据类)
3.ApkResponseBody(自定义继承OKHttp的ResponseBody的类)重点
4.RxBus(使用RxJava实现的‘EventBus')重点
5.UpdateApkService(更新服务,在这里开启下载和订阅下载进度)重点
6.UpdateHelper(检查更新、弹出更新对话框)
7.UpdateManager(调用ApiManager接口进行下载)
先讲一下OKHttp里对拦截器的操作,我们在拦截器里拿到请求到的响应,对响应信息进行一些封装并通过RxBus发送出去。接下来看重点代码。
ApkResponseBody:
public class ApkResponseBody extends ResponseBody {
private Response originalResponse;//原responsebody
public ApkResponseBody(Response originalResponse) {
this.originalResponse = originalResponse;
}
/**
* 返回内容类型
*
* @return
*/
@Override
public MediaType contentType() {
return originalResponse.body().contentType();
}
/**
* 内容总长度
* @return
*/
@Override
public long contentLength() {
return originalResponse.body().contentLength();
}
/**
* 返回缓存源,类似于io中的BufferedReader
*
* @return
*/
@Override
public BufferedSource source() {
return Okio.buffer(new ForwardingSource(originalResponse.body().source()) {
long totalRead = 0;
//返回读取的长度
@Override
public long read(Buffer sink, long byteCount) throws IOException {
long bytesRead = super.read(sink, byteCount);
totalRead += bytesRead == -1 ? 0 : bytesRead;
Log.i("test", "本次下载:" + bytesRead);
Log.i("test", "总共下载:" + totalRead);
RxBus.getDefault().post(new ApkLoadingBean(contentLength(), totalRead));
return bytesRead;
}
@Override
public Timeout timeout() {
return super.timeout();
}
@Override
public void close() throws IOException {
super.close();
}
@Override
public String toString() {
return super.toString();
}
});
}
}
在source()方法中拿到下载长度和文件总长度,封装成Bean通过RxBus发送出去。并在ApiManager中初始化Retrofit的时候设置给OKHttp。
OkHttpClient client = new OkHttpClient().newBuilder()
.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Response originalResponse = chain.proceed(chain.request());
return originalResponse
.newBuilder()
.body(new ApkResponseBody(originalResponse))
.build();
}
}).build();
RxBus:
public class RxBus {
private static volatile RxBus mInstance;
private final Subject