下载更新apk,基本上每个app都需要的功能,来看看吧,肯定有你想要的,以前都是自己写,近期想借助第三方的一个库来做,功能齐全,感觉不错,记录使用过程,虽然官方也有使用教程,不过毕竟粗略,网上也能搜到,不过基本都是复制的

首先下载库,地址改成我们自己的,检查地址就让它了,这个根据自己的业务调整,也能自定义

接下来是参数介绍

参数大多数一看就懂,这里介绍下md5效验,此字段为必填字段,不过有的时候不想效验,或者测试的时候想先调通了,然后在跟后台沟通加上效验,这样就不能直接gradle配置引用了,得下载源码,更改里面的代码了,不然就得按照文档说明来

我想很多人都不愿意一开始去搞什么md5效验,虽然它的demo是可以用的,不过还是得改成自己的才安心,但是改成自己的又会效验失败,你不传又不行,所以没办法了,只能改源代码

info.size字段是下载大小,这是为了提示框展示作用,可以自己动态获取

源代码里面很多回调,有点绕,不过代码也就那么点,找找也就找到了

此处是返回效验结果,注释掉代码,然后return true就行了,命名默认是md5命名

然后还有后台静默下载,这里也提供了静默下载,然后在状态栏里显示进度

直接调用demo的方法就好了

立即下载回调download方法,下载是继承asynctask下载

然后里面的弹框比较简单的alertdialog写的,我觉得这样简单蛮好的,可是现实是残酷的,很多都是需要自己定制弹框,调用接口获取数据啊,加样式啊,都是正常,那么默认的肯定满足不了你了,可是它是写在库里面的,要改的话得自己另外写,然后替换掉它写的

我是自己写了个帮助类,把它原来的注释了

progress也换成了自己了

它原本是在start里面的,需求如此,只能改

还有一个就是强制更新功能,有的需求强制更新,初始化弹出提示更新框,然后调用接口获取是否强制更新,如果是就点击后台静默下载,可以正常操作界面,如果否,就弹出下载框下载,而它原本的强制更新不是这样的,还有静默下载,是不弹框的,直接就后台下载了,这里也好改,把一个判断注释掉就好了,找到强制更新判断的地方

注释后发现ok了,其它都不用改,下面的doPrompt方法就是弹框下载,doDownload就是不弹框下载,这里只是一个判断,而真正是否静默下载还是它原来的参数来决定的,所以把这里改了参数正常传进去,一切ok

最后就是md5验证了,把服务器的md5字段传进去,然后把前面注释的代码解开,这个要先跟后台协商好,默认的是 String.format("%1$032x", new Object[]{var5}) ,宽度为32,我这边服务器上的是08x,所以要改一下

这里网上的方法是与运算之类的,亲自测了一下,没有问题

我这里还是用它默认的解密方法,把宽度改一下就好了,至于format用法也简单

下面是打印的日志信息,看到输出结果估计也就明白这是怎么回事了

Log.e("format","08d "+String.format("%1$08d", 120504));
Log.e("format","08x "+String.format("%1$08x", 120504));
Log.e("format","016d "+String.format("%1$016d", 120504));
Log.e("format","016x "+String.format("%1$016x", 120504)); E/format: 08d 00120504
E/format: 08x 0001d6b8
E/format: 016d 0000000000120504
E/format: 016x 000000000001d6b8

运行程序,发现通过

然后不知道到这里你们发现没有,就是它初始化的时候会传入一个checkurl,这里其实就是你的接口地址,然后它自带写了一个网络访问,再把请求后的数据设置到其中,提供下载操作,看它的下载操作就知道了

 @Override
public void check(ICheckAgent agent, String url) {
HttpURLConnection connection = null;
try {
connection = (HttpURLConnection) new URL(url).openConnection();
connection.setRequestProperty("Accept", "application/json"); if (mPostData == null) {
connection.setRequestMethod("GET");
connection.connect();
} else {
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setInstanceFollowRedirects(false);
connection.setUseCaches(false);
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("Content-Length", Integer.toString(mPostData.length));
connection.getOutputStream().write(mPostData);
} if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
agent.setInfo(UpdateUtil.readString(connection.getInputStream()));
} else {
agent.setError(new UpdateError(UpdateError.CHECK_HTTP_STATUS, "" + connection.getResponseCode()));
}
} catch (IOException e) {
e.printStackTrace();
agent.setError(new UpdateError(UpdateError.CHECK_NETWORK_IO));
} finally {
if (connection != null) {
connection.disconnect();
}
}
}

这就是最外层的check方法,url就是你传入的checkurl,如果你不传不用它的,就会出现空指针错误,然后在调用 agent.setInfo 设置值到 UpdateAgent 这个类里面,这个类是具体的下载类了,为什么讲这个

我们自己肯定会有检查更新的接口,肯定会传入参数,回调肯定会做逻辑处理,在它里面这样实在不方便,它传入的checkurl添加参数什么的也得改,不喜欢,所以想把这个检查更新的功能去掉,只要下载功能,检查更新我们自己处理

改起来就有点大了,不像前面的那些,小改动,不过看懂了也好改,从最外层开始进入,你需要一个打开方式,外面这多设置调用方法,其实说到底就是传入回调和数据进入,然后提供检查更新和下载操作

最外层设置的数据在 UpdateManager 这个类里面,点进入看就是了,最重要的就是check方法了

 public void check() {
long now = System.currentTimeMillis();
if (now - sLastTime < 3000) {
return;
}
sLastTime = now; if (TextUtils.isEmpty(mUrl)) {
mUrl = UpdateUtil.toCheckUrl(mContext, sUrl, sChannel);
} UpdateAgent agent = new UpdateAgent(mContext, mUrl, mIsManual, mIsWifiOnly, mNotifyId,isSilent);
if (mOnNotificationDownloadListener != null) {
agent.setOnNotificationDownloadListener(mOnNotificationDownloadListener);
}
if (mOnDownloadListener != null) {
agent.setOnDownloadListener(mOnDownloadListener);
}
if (mOnFailureListener != null) {
agent.setOnFailureListener(mOnFailureListener);
}
if (mChecker != null) {
agent.setChecker(mChecker);
} else {
agent.setChecker(new UpdateChecker(mPostData));
}
if (mParser != null) {
agent.setParser(mParser);
}
if (mDownloader != null) {
agent.setDownloader(mDownloader);
}
if (mPrompter != null) {
agent.setPrompter(mPrompter);
}
if (endListener != null){
UpdateAgent.endListener = endListener;
}
agent.check();
}
}

在这个方法里面可以看到,基本数据都转移到了 UpdateAgent 这个类里面去了,但是调试你会发现,你不传入检查地址url 通过不了,因为有这么一段

这也好办,把里面的空指针处理下就好了,价格空指针判断让它继续往下走,下面就到了关键的步骤了

进入了这里了,进入这里面做什么,在进去看

 void doCheck() {
new AsyncTask<String, Void, Void>() {
@Override
protected Void doInBackground(String... params) {
if (mChecker == null) {
mChecker = new UpdateChecker();
}
mChecker.check(UpdateAgent.this, mUrl);
return null;
} @Override
protected void onPostExecute(Void aVoid) {
doCheckFinish();
}
}.execute();
}

一步步进入,发现这里就是http访问checkurl了,然后回调返回数据给到 UpdateAgent这个类里面去

然后发现回到了 UpdateAgent这里,这里做更新下载操作,调用的也是外层传入的数据UpdateInfo,那么就好办了,外层的检查更新接口不要,http访问去掉,然后因为我们在最外层已经有了 UpdateInfo 这个类了,所以可以直接传进去,然后就可以跳过检查这个步骤了

添加一个实体类,这也是它自带的实体类,生成设置获取方法

然后在最外层去掉不必要的方法,把实体类提出来直接设置进去

 UpdateManager.create(context)
.setManual(true)// 在设置界面点击检查更新
.setNotifyId(998)//notify唯一标识
.setUserInfo(info)
.check();

精简很多了,接下来就是里面修改了,前面就说了,check方法里面是直接传值的,那我们就不需要回调了,直接传入进去

 public void check() {
long now = System.currentTimeMillis();
if (now - sLastTime < 3000) {
return;
}
sLastTime = now; if (TextUtils.isEmpty(mUrl)) {
mUrl = UpdateUtil.toCheckUrl(mContext, sUrl, sChannel);
} UpdateAgent agent = new UpdateAgent(mContext, mUrl, mIsManual, mIsWifiOnly, mNotifyId);
if (mOnNotificationDownloadListener != null) {
agent.setOnNotificationDownloadListener(mOnNotificationDownloadListener);
}
if (mOnDownloadListener != null) {
agent.setOnDownloadListener(mOnDownloadListener);
}
if (mOnFailureListener != null) {
agent.setOnFailureListener(mOnFailureListener);
}
if (mChecker != null) {
agent.setChecker(mChecker);
} else {
agent.setChecker(new UpdateChecker(mPostData));
}
if (mParser != null) {
agent.setParser(mParser);
}
if (mDownloader != null) {
agent.setDownloader(mDownloader);
}
if (mPrompter != null) {
agent.setPrompter(mPrompter);
}
if (endListener != null){
UpdateAgent.endListener = endListener;
}
if (mInfo != null)
agent.setInfo(mInfo);
agent.check();
}
}

当然,这里上面判断checkurl地址的还得加个空指针判断,不然走不下去

然后就是修改关键地方了,跳过检查步骤,直接下载了,因为我们数据都有了,不需要去用它的网络请求了

 void doCheck() {
if (mUrl == null || mUrl.isEmpty()) {
// setInfo();
doCheckFinish();//直接下载,不检查
return;
}
new AsyncTask<String, Void, Void>() {
@Override
protected Void doInBackground(String... params) {
if (mChecker == null) {
mChecker = new UpdateChecker();
}
mChecker.check(UpdateAgent.this, mUrl);
return null;
} @Override
protected void onPostExecute(Void aVoid) {
doCheckFinish();
}
}.execute();
}

下面就是它启动的网络访问请求,所以我们直接在最上面给它截断了,然后直接调用下载方法,因为我们在上面已经传入了 UpdateInfo 实体进入了 UpdateAgent 类里面, doCheckFinish 方法就在 UpdateAgent里面,所以什么都不用改,它就会自动根据参数需求更新下载了

而且这还解决了一个问题,就是你用它自带的检查更新会导致网络慢的时候过好久才弹框出来,好像卡住了一样,而直接跳过这个步骤就没有这个问题了,直接开始下载,不然只有在它原基础上加个加载弹框什么的

到这里就要结束了,(☄⊙ω⊙)☄

更新下载库update绝对详解的更多相关文章

  1. 全网最全的Windows下Python2 / Python3里正确下载安装用来向微信好友发送消息的itchat库(图文详解)

    不多说,直接上干货! 建议,你用Anaconda2或Anaconda3. 见 全网最全的Windows下Anaconda2 / Anaconda3里正确下载安装用来向微信好友发送消息的itchat库( ...

  2. SQL Update 语句详解

    SQL Update 语句详解   Update 语句 Update 语句用于修改表中的数据. 语法: UPDATE 表名称 SET 列名称 = 新值 WHERE 列名称 = 某值 Person: L ...

  3. 【Linux开发】Linux下jpeglib库的安装详解

    Linux下jpeglib库的安装详解 首先要下载所需的库压缩包:jpegsrc.v6b.tar.gz或 jpegsrc.v8b.tar.gz 然后将下载的压缩包随便放在和解压到你喜欢的地方. # t ...

  4. 【Solr】索引库查询界面详解

    目录 索引库查询界面详解 回到顶部 索引库查询界面详解 q:主查询条件.完全支持lucene语法.还进行了扩展. fq:过滤查询.是在主查询条件查询结果的基础上进行过滤.例如:product_pric ...

  5. c/c++ 标准库 插入迭代器 详解

    标准库 插入迭代器 详解 插入迭代器作用:copy等函数不能改变容器的大小,所以有时copy先容器是个空的容器,如果不使用插入迭代器,是无法使用copy等函数的. 例如下面的代码就是错误的: list ...

  6. c/c++ 标准库 bind 函数 详解

    标准库 bind 函数 详解 bind函数:接收一个函数名作为参数,生成一个新的函数. auto newCallable = bind(callbale, arg_list); arg_list中的参 ...

  7. CentOS 最新版的下载地址 + 版本选择详解

    CentOS 最新版的下载地址 + 版本选择详解 发现越来越多的机关单位.事业单位开始使用 Linux 作为主要服务器,毕竟,Linux的稳定性和高效性是众所周知的,所以我也打算把自己这一块技术加强一 ...

  8. python中requests库使用方法详解

    目录 python中requests库使用方法详解 官方文档 什么是Requests 安装Requests库 基本的GET请求 带参数的GET请求 解析json 添加headers 基本POST请求 ...

  9. 全网最全的Windows下Anaconda2 / Anaconda3里正确下载安装用来向微信好友发送消息的itchat库(图文详解)

    不多说,直接上干货!  Anaconda2 里 PS C:\Anaconda2\Scripts> PS C:\Anaconda2\Scripts> pip.exe install itch ...

随机推荐

  1. LeetCode题解38.Count and Say

    38. Count and Say The count-and-say sequence is the sequence of integers beginning as follows: 1, 11 ...

  2. [Swift]LeetCode861. 翻转矩阵后的得分 | Score After Flipping Matrix

    We have a two dimensional matrix A where each value is 0 or 1. A move consists of choosing any row o ...

  3. 起底区块链人脸识别黑马,一个没有人像的人脸识别:iFace Chain(爱妃链)

    近几年来,人脸识别技术可谓在移动互联网中得到了空前广泛应用,从银行APP免密转账,人脸快捷支付到证券人脸开户,人脸识别技术已经应用到了移动互联的诸多应用场景.互联网无处不在的今天,便捷与安全貌似是一个 ...

  4. 必须知道的Java八大排序算法

    冒泡排序.简单选择.直接插入.快速排序.堆排序.希尔排序.归并排序.基数排序. 将其按排序方式分类如下图所示: 1.冒泡排序: 基本思想——在要排序的一组数中,对当前还未排好序的范围内的全部数据,自上 ...

  5. 使用vue+ivew做2048小游戏

    首先先弄页面 废话不多说 上代码 静态页面代码 <template> <div class="main"> <div class="top& ...

  6. SpringCloud(6)---熔断降级理解、Hystrix实战

    SpringCloud(6)---熔断降级理解.Hystrix实战 一.概念 1.为什么需要熔断降级 (1)需求背景 它是系统负载过高,突发流量或者网络等各种异常情况介绍,常用的解决方案. 在一个分布 ...

  7. asp.net core系列 33 EF查询数据 (2)

    一. 原生SQL查询 接着上篇讲.通过 Entity Framework Core 可以在使用关系数据库时下降到原始 SQL 查询. 在无法使用 LINQ 表达要执行的查询时,或因使用 LINQ 查询 ...

  8. EFCore合并多条迁移记录

    方法来自 merge-migrations-in-entity-framework-core 更新数据库到最新结构 删除迁移目录下的所有迁移脚本 新建一个迁移 注释掉Up()和Down()方法中的代码 ...

  9. 【朝花夕拾】Android性能篇之(二)Java内存分配

    前言        在内存方面,相比于C/C++程序员,咱们java系程序员算是比较幸运的,因为对于内存的分配和回收,都交给了JVM来处理了,而不需要手动在代码中去完成.有了虚拟机内存管理机制,也就不 ...

  10. android 垃圾回收机制

    1.垃圾收集算法的核心思想 java语言提供了自动的GC机制,系统会经常检查内存,采用对象引用计数的方式,将引用次数为0的对象回收.这样可以防止两个危险:(1)防止无用对象占用内存资源 (2)防止有用 ...