APP自动增量更新

抽取的Android自动更新库,目的是几行代码引入更新功能,含服务端代码,欢迎Star,欢迎Fork,谢谢~

博客同步自:个人博客主页
代码github: https://github.com/itlwy/AppSmartUpdate

目录

  • 功能介绍
  • 流程图
  • 效果图与示例apk
  • 如何引入
  • 更新清单文件
  • 简单使用
  • 详细说明
  • 差分包生成(服务端)
  • 依赖

功能介绍

  • 支持全量更新apk,直接升级到最新版本
  • 支持增量更新,只下载补丁包升级
  • 设置仅在wifi环境下更新
  • 支持外部注入网络框架(库默认使用okhttp)
  • 支持前台和后台自动更新
  • 支持强制更新
  • 支持对外定制更新提示和更新进度界面
  • 记忆下载
  • 含发布功能后台服务端github (Node.js实现)

流程图

效果图与示例apk


点击下载 smart-update.apk

如何引入

Gradle引入

step 1

Add the JitPack repository to your build file

 allprojects {repositories {...maven { url 'https://jitpack.io' }}}

Step 2

Add the dependency

dependencies {implementation 'com.github.itlwy:AppSmartUpdate:v1.0.6'}

更新清单文件

该清单放置在静态服务器以供App访问,主要用于判断最新的版本,及要更新的版本资源信息等(示例见仓库根目录下的resources目录或直接访问后台代码 github),清单由服务端程序发布apk时生成,详见后台示例:github

{"minVersion": 100, // app最低支持的版本代码(包含),低于此数值的app将强制更新"minAllowPatchVersion": 100, // 最低支持的差分版本(包含),低于此数值的app将采取全量更新,否则采用差量"newVersion": 101, // 当前最新版本代码"tip": "test update", // 更新提示"size": 1956631,   // 最新apk文件大小"apkURL": "https://raw.githubusercontent.com/itlwy/AppSmartUpdate/master/resources/app/smart-update.apk", // 最新apk 绝对url地址,也可用相对地址,如下方的"patchURL"字段"hash": "ea97c8efa490a2eaf7d10b37e63dab0e", // 最新apk文件的md5值"patchInfo": {  // 差分包信息"v100": { // v100表示-版本代码100的apk需要下载的差分包"patchURL": "v100/100to101.patch", //差分包地址,相对此UpdateManifest.json文件的地址,也可用绝对地址"tip": "101 version", // 提示"hash": "ea97c8efa490a2eaf7d10b37e63dab0e", // 合成后apk(即版本代码101)的文件md5值"size": 1114810 // 差分包大小}}
}

简单使用

1.初始化

public class MyApplication extends Application {@Overridepublic void onCreate() {super.onCreate();//推荐在Application中初始化Config config = new Config.Builder().isDebug(true).build(this);UpdateManager.getInstance().init(config);}
}

2.调用

public class MainActivity extends AppCompatActivity implements View.OnClickListener {private Button mUpdateBtn;private String manifestJsonUrl = "https://raw.githubusercontent.com/itlwy/AppSmartUpdate/master/resources/UpdateManifest.json";private IUpdateCallback mCallback;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mUpdateBtn = (Button) findViewById(R.id.update_btn);mUpdateBtn.setOnClickListener(this);}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.update_btn:UpdateManager.getInstance().update(this, manifestJsonUrl, null);break;}}
}

详细说明

注册通知回调

  • 其他activity界面需要获知后台更新情况
public void register(IUpdateCallback callback) {...}public void unRegister(IUpdateCallback callback) {...}public interface IUpdateCallback {/*** 通知无新版本需要更新,运行在主线程*/void noNewApp();/*** 自动更新准备开始时回调,运行在主线程,可做一些提示等*/void beforeUpdate();/*** 自动更新的进度回调(分增量和全量更新),运行在主线程** @param percent     当前总进度百分比* @param totalLength 更新总大小(全量为apk大小,增量为全部补丁大小和)* @param patchIndex  当前更新的补丁索引(从1开始)* @param patchCount  需要更新的总补丁数(当为0时表示是增量更新)*/void onProgress(int percent, long totalLength, int patchIndex, int patchCount);/*** 下载完成,准备更新,运行在主线程*/void onCompleted();/*** 异常回调,运行在主线程** @param error 异常信息*/void onError(String error);/*** 用户取消了询问更新对话框*/void onCancelUpdate();/*** 取消了更新进度对话框,压入后台自动更新,此时由通知栏通知进度*/void onBackgroundTrigger();
}

网络框架注入

默认使用okhttp,也可由外部注入,只需实现如下的IHttpManager接口,然后通过new Config.Builder().httpManager(new OkhttpManager())注入即可

public interface IHttpManager {IResponse syncGet(@NonNull String url, @NonNull Map<String, String> params) throws IOException;/*** 异步get** @param url      get请求地址* @param params   get参数* @param callBack 回调*/void asyncGet(@NonNull String url, @NonNull Map<String, String> params, @NonNull Callback callBack);/*** 异步post** @param url      post请求地址* @param params   post请求参数* @param callBack 回调*/void asyncPost(@NonNull String url, @NonNull Map<String, String> params, @NonNull Callback callBack);/*** 下载** @param url      下载地址* @param path     文件保存路径* @param fileName 文件名称* @param callback 回调*/void download(@NonNull String url, @NonNull String path, @NonNull String fileName, @NonNull FileCallback callback);
}

定制更新交互界面

每个应用的风格都可能是不一样的,因此这里也支持自定义弹出的提示框和进度框,详细见如下代码示例:

  1. 初始化config时需要将内部默认的弹框屏蔽掉

     public class MyApplication extends Application {@Overridepublic void onCreate() {super.onCreate();Config config = new Config.Builder().isShowInternalDialog(false).build(this);UpdateManager.getInstance().init(config);}
    }
    
  2. 自定义对话框,如下(详细代码在MainActivity.java里):

 public void registerUpdateCallbak() {mCallback = new IUpdateCallback() {@Overridepublic void noNewApp() {Toast.makeText(MainActivity.this, "当前已是最新版本!", Toast.LENGTH_LONG).show();}@Overridepublic void hasNewApp(AppUpdateModel appUpdateModel, UpdateManager updateManager, final int updateMethod) {AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);mDialog = builder.setTitle("自动更新提示").setMessage(appUpdateModel.getTip()).setPositiveButton("更新", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {UpdateManager.getInstance().startUpdate(updateMethod);}}).setNegativeButton("取消", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {}}).create();mDialog.show();}@Overridepublic void beforeUpdate() {// 更新开始mProgressDialog = new ProgressDialog(MainActivity.this);mProgressDialog.setTitle("更新中...");mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);mProgressDialog.setMessage("正在玩命更新中...");mProgressDialog.setMax(100);mProgressDialog.setProgress(0);mProgressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {@Overridepublic void onCancel(DialogInterface dialog) {// 退到后台自动更新,进度由通知栏显示if (UpdateManager.getInstance().isRunning()) {UpdateManager.getInstance().onBackgroundTrigger();}}});mProgressDialog.show();}@Overridepublic void onProgress(int percent, long totalLength, int patchIndex, int patchCount) {String tip;if (patchCount > 0) {tip = String.format("正在下载补丁%d/%d", patchIndex, patchCount);} else {tip = "正在下载更新中...";}mProgressDialog.setProgress(percent);mProgressDialog.setMessage(tip);}@Overridepublic void onCompleted() {mProgressDialog.dismiss();}@Overridepublic void onError(String error) {Toast.makeText(MainActivity.this, error, Toast.LENGTH_LONG).show();mProgressDialog.dismiss();}@Overridepublic void onCancelUpdate() {}@Overridepublic void onBackgroundTrigger() {Toast.makeText(MainActivity.this, "转为后台更新,进度由通知栏提示!", Toast.LENGTH_LONG).show();}};UpdateManager.getInstance().register(mCallback);}

差分包合成(jni)

​ 此部分采用的差分工具为开源bsdiff,用于生成.patch补丁文件,采用jni方式封装一个.so库供java调用,详见"smartupdate"库里的main/cpp目录源码,过程比较简单,就是写个jni的方法来直接调用bsdiff库,目录结构如下:

main-cpp-bzip2-CMakeLists.txt-patchUtils.c-patchUtils.h-update-lib.cpp

因为bsdiff还依赖了bzip2,所以这里涉及多个源文件编译链接问题,需要在CMakeLists.txt稍作修改:

# 将当前 "./src/main/cpp" 目录下的所有源文件保存到 "NATIVE_SRC" 中,然后在 add_library 方法调用。
aux_source_directory( . NATIVE_SRC )
# 将 "./src/main/cpp/bzip2" 目录下的子目录bzip2保存到 "BZIP2_BASE" 中,然后在 add_library 方法调用。
aux_source_directory( ./bzip2 BZIP2_BASE )
# 将 BZIP2_BASE 增加到 NATIVE_SRC 中,这样目录的源文件也加入了编译列表中,当然也可以不加到 NATIVE_SRC,直接调用add_library。
list(APPEND NATIVE_SRC ${BZIP2_BASE})add_library( # Sets the name of the library.update-lib# Sets the library as a shared library.SHARED# Provides a relative path to your source file(s).${NATIVE_SRC})

差分包生成

​ 服务端见github ,使用时将manifestJsonUrl改成部署的服务器地址即可,如下示例代码片段的注释处

public class MainActivity extends AppCompatActivity {private String manifestJsonUrl = "https://raw.githubusercontent.com/itlwy/AppSmartUpdate/master/resources/UpdateManifest.json";
//    private String manifestJsonUrl = "http://192.168.2.107:8000/app/UpdateManifest.json";...
}

依赖

  • okhttp : com.squareup.okhttp3:okhttp:3.11.0
  • gson : com.google.code.gson:gson:2.8.0
  • numberprogressbar : com.daimajia.numberprogressbar:library:1.4@aar

本文由Weiye Lee原创,转载请注明来源:
https://blog.csdn.net/Weiye__Lee/article/details/82749079

android APP自动增量更新相关推荐

  1. Android App自动更新解决方案(DownloadManager)

    Android App自动更新解决方案(DownloadManager) 参考文章: (1)Android App自动更新解决方案(DownloadManager) (2)https://www.cn ...

  2. android通知栏应用程序更新,Android App自动更新之通知栏下载

    本文实例为大家分享了Android App自动更新通知栏下载的具体代码,供大家参考,具体内容如下 版本更新说明 这里有调用UpdateService启动服务检查下载安装包等 1. 文件下载,下完后写入 ...

  3. Android APP 自动更新实现(适用Android9.0)

    Android App自动更新基本上是每个App都需具备的功能,参考网上各种资料,自己整理了下,先来看看大致的界面: 一.实现思路: 1.发布Android App时,都会生成output-metad ...

  4. Android 版本更新,支持增量更新

    AppSmartUpdate 项目地址:itlwy/AppSmartUpdate 简介: a smart lib for updating app / Android 版本更新,支持增量更新 更多:作 ...

  5. Android 如何实现增量更新

    什么是增量更新? 现在的APP安装包体积越来越大,几百兆甚至上G的,当APP更新时不再是消耗大量的流量下载一个完整安装包,而是消耗相对很少的流量下载一个增量包(差分包),采用谷歌Smart App U ...

  6. android app 自动更新,AndroidUpdateDemo

    Android课程-App更新策略 @(Android) 第一节 课程介绍 概述 App更新是应用当中很常见的一个功能,基本上联网的app都应该具备这样的功能,对于更新迭代比较快速的产品,应用更新升级 ...

  7. Android友盟增量更新

    1.增量升级的原理  增量更新的原理就是将本地apk与服务器端最新版本比对,并得到差异包.比如现在的版本是1.1.4,大小是7.2M,新版本是1.1.5.大小是7.3M.我们发现两个版本只有0.1M的 ...

  8. 使用友盟进行app的增量更新

    本文转自:http://blog.csdn.net/itachi85/article/details/47357313 正文: 1.增量升级的原理  增量更新的原理就是将本地apk与服务器端最新版本比 ...

  9. android+仿友盟更新,android友盟增量更新

    1.增量升级的原理 增量更新的原理就是将本地apk与服务器端最新版本比对,并得到差异包.比如现在的版本是1.1.4,大小是7.2M,新版本是1.1.5.大小是7.3M.我们发现两个版本只有0.1M的差 ...

最新文章

  1. asm 比 ucontext 快
  2. 用JSLint精炼提升JavaScript代码
  3. 15张令人震撼的物理动图,看完惊呆了!
  4. Python中出现:RunTimeError:implement_array_function method already has a docstring.异常解决
  5. Lily have a dog
  6. 马云电脑水平曝光;快狗打车回应裁员50% ;华为邀请开发者加入应用商店 | 极客头条...
  7. LoadRunner 录制常见错误解决方法
  8. 华为算法精英赛(题3:概率计算)
  9. linux iptables服务及相关命令
  10. ThinkPad T400 笔记本详细拆机过程 清理风扇(图文教程)
  11. Python爬虫 - 理解深度优先和广度优先
  12. 帆软报表多数据集关联合并操作
  13. 动态MAC地址和静态MAC地址
  14. Windows动态链接库使用详解
  15. 占据栅格地图构建(Occupancy Grid Map)
  16. 【编程题】【Scratch二级】2019.09 制作蝙蝠冲关游戏
  17. 雷达的工作原理示意图_雷达的工作原理是什么?
  18. python公司网站毕业设计开题报告
  19. nyoj995硬币找零(dp)
  20. 无线收发芯片可应用在哪些领域?

热门文章

  1. Tomcate安装配置
  2. 新知实验室 TRTC实时音视频
  3. syslog配置及测试
  4. C# mschart 控件 框选 删除部分数据 及游标CursorX CursorY 使用
  5. 网页游戏mysql修改_大天使之剑奇迹网页游戏 一键服务端+架设教程+修改方法
  6. pyqt5+pyinstaller图标ico制作说明
  7. layui网站后台管理系统框架模板
  8. python signal滤波器使用说明
  9. 程序员被人喜欢的13点原因
  10. Intel Realsense D455 D435i D415 T265 3D实感硬件对比