本文实例为大家分享了Retrofit2 RxJava2实现Android应用自动更新,具体内容如下
<强>功能解析强>
自动更新可以说已经是应用的标配了,很多第三方平台也都支持这个功能,最近手头上的项目需要加入这个应用自动更新,考虑到项目里有用到Retrofit2和RxJava2,于是打算使用它俩自己实现这个功能。
分析应用自动更新,可以分为以下三个功能点:
1。APK文件的下载
2.下载进度的实时更新显示
3 .下载完成后的自动安装
其中比较难的一点是下载进度的实时更新显示,更难的是如何优雅的进行下载进度的更新显示,这也是为什么我用Retrofit2和RxJva2实现的原因。
用改造过的人都知道他的内部是基于OkHttp实现的,OkHttp大家可能都不陌生,本次解决如何优雅的进行下载进度的更新显示的关键就在OkHttp的拦截器中,拦截器可谓是OkHttp的一大精髓,通过拦截器我们可以拿到Http的请求和响应信息,拿到了这些,你想干什么都行了。本次解决问题的核心就是在拦截器中拿到下载内容的长度并通过自定义的RxBus发送事件将下载信息发送出去,然后在合适的地方拿到这些下载信息,通过通知实时展示下载进度。
先上一张应用自动更新的流程图
<强>功能实现强>
首先根据功能需求我创建了七个类:
1。ApiManager(改造初始化和Api接口定义)
2.ApkLoadingBean(下载长度和文件总长度的数据类)
3. apkresponsebody(自定义继承OKHttp的ResponseBody的类)4. rxbus(使用RxJava实现的EventBus) 5. updateapkservice(更新服务,在这里开启下载和订阅下载进度)6。UpdateHelper(检查更新,弹出更新对话框)
7. updatemanager(调用ApiManager接口进行下载)
先讲一下OKHttp里对拦截器的操作,我们在拦截器里拿到请求到的响应,对响应信息进行一些封装并通过RxBus发送出去。接下来看重点代码。
<强> ApkResponseBody: 强>
公开课ApkResponseBody延伸ResponseBody { 私人响应originalResponse;//原responsebody 公共ApkResponseBody(响应originalResponse) { 这一点。originalResponse=originalResponse; }/* * *返回内容类型 * * @return */@Override 公共MediaType contentType () { .contentType返回originalResponse.body () (); }/* * *内容总长度 * @return */@Override 公共长contentLength () { .contentLength返回originalResponse.body () (); }/* * *返回缓存源,类似于io中的BufferedReader * * @return */@Override 公共BufferedSource源(){ Okio返回。.source缓冲区(新ForwardingSource (originalResponse.body () ()) { 长totalRead=0;//返回读取的长度 @Override 公共长阅读(缓冲水池,长byteCount)抛出IOException { 长bytesRead=超级。读(水槽,byteCount); totalRead +=bytesRead==1 & # 63;0:bytesRead; 日志。我(“测试”、“本次下载:“+ bytesRead); 日志。我(“测试”、“总共下载:“+ totalRead); RxBus.getDefault ()。(新ApkLoadingBean (contentLength (), totalRead)); 返回bytesRead; } @Override 公共超时超时(){ 返回super.timeout (); } @Override 公共空间close()抛出IOException { super.close (); } @Override 公共字符串toString () { 返回super.toString (); } }); } }
在源()方法中拿到下载长度和文件总长度,封装成豆通过RxBus发送出去。并在ApiManager中初始化改造的时候设置给OKHttp。
.newBuilder OkHttpClient客户=new OkHttpClient () () .addInterceptor(新的拦截器(){ @Override 公开回应拦截(链链)抛出IOException { 响应originalResponse=chain.proceed (chain.request ()); 返回originalResponse .newBuilder () .body(新ApkResponseBody (originalResponse)) .build (); } }).build ();>之前<强> RxBus: 强>
公开课RxBus { 私有静态稳定RxBus mInstance; 私人最终Subject