下载更新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. Python公众号开发(二)—颜值检测

    上篇文章,我们把自己的程序接入了微信公众号,并且能把用户发送的文本及图片文件原样返回.今天我们把用户的图片通过腾讯的AI平台分析后再返回给用户. 为了防止我的文章被到处转载,贴一下我的公众号[智能制造 ...

  2. CS20SI-tensorflow for research笔记: Lecture3

    本文整理自知乎专栏深度炼丹,转载请征求原作者同意. 本文的全部代码都在原作者GitHub仓库github CS20SI是Stanford大学开设的基于Tensorflow的深度学习研究课程. Tens ...

  3. [SQL]LeetCode183. 从不订购的客户 | Customers Who Never Order

    Suppose that a website contains two tables, the Customers table and the Orders table. Write a SQL qu ...

  4. [Swift]LeetCode838. 推多米诺 | Push Dominoes

    There are N dominoes in a line, and we place each domino vertically upright. In the beginning, we si ...

  5. iOS学习——(转)多线程

    转载自:iOS多线程全套:线程生命周期,多线程的四种解决方案,线程安全问题,GCD的使用,NSOperation的使用 一.多线程的基本概念 进程:可以理解成一个运行中的应用程序,是系统进行资源分配和 ...

  6. [Abp 源码分析]十六、后台作业与后台工作者

    0. 简介 在某些时候我们可能会需要执行后台任务,或者是执行一些周期性的任务.比如说可能每隔 1 个小时要清除某个临时文件夹内的数据,可能用户会要针对某一个用户群来群发一组短信.前面这些就是典型的应用 ...

  7. 【CDH篇】---CDH从初识到搭建到应用

    一.前述 CDH(Cloudera's Distribution, including Apache Hadoop)是Hadoop众多分支中的一种,由Cloudera维护,基于稳定版本的Apache ...

  8. 开发环境配置:jdk8的详细安装教程&&tomact的详细安装教程&&java环境变量的配置&&tomcat启动总失败原因

    1.下载 链接: http://pan.baidu.com/s/1i57HZKx 密码: cnb4 2.详细安装过程 3.下载地址 链接: http://pan.baidu.com/s/1mi6VUp ...

  9. 双飞翼布局的改造 box-sizing和margin负值的应用

    box-sizing + margin负值 升级双飞翼布局 一.box-sizing属性 .content-size, .border-size{ width: 200px; height: 100p ...

  10. 【Java基础】【03运算符&if语句】

    03.01_Java语言基础(逻辑运算符的基本用法)(掌握) A:逻辑运算符有哪些 &,|,^,! &&,|| B:案例演示 逻辑运算符的基本用法 注意事项: a:逻辑运算符一 ...