AppSmartUpdate

项目地址:itlwy/AppSmartUpdate

简介: a smart lib for updating app / Android 版本更新,支持增量更新

更多:作者   提 Bug

标签:

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

目录

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

功能介绍

  • [x] 支持全量更新 apk,直接升级到最新版本
  • [x] 支持增量更新,只下载补丁包升级
  • [x] 设置仅在 wifi 环境下更新
  • [x] 支持外部注入网络框架(库默认使用 okhttp)
  • [x] 支持前台或后台自动更新
  • [x] 支持基于版本的强制更新
  • [x] 支持对外定制更新提示和更新进度界面
  • [x] 含发布功能后台服务端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.7'}

更新清单文件

该清单放置在静态服务器以供 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

License

   Copyright 2018 lwyLicensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License athttp://www.apache.org/licenses/LICENSE-2.0Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Android 版本更新,支持增量更新相关推荐

  1. Android友盟增量更新

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

  2. android APP自动增量更新

    APP自动增量更新 抽取的Android自动更新库,目的是几行代码引入更新功能,含服务端代码,欢迎Star,欢迎Fork,谢谢- 博客同步自:个人博客主页 代码github: https://gith ...

  3. Android 如何实现增量更新

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

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

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

  5. Android APP增量更新

    最近项目推进app的增量更新方案,特意看了几篇文章,先来两个博客地址 http://my.oschina.net/liucundong/blog/160436 https://github.com/c ...

  6. Android应用内增量更新

    #Android 增量更新实现 原本来腾讯课堂中了解到了一些关于增量更新的知识,特地写一篇博客来记录下. 手机端实现 https://github.com/ItsFated/DiffPatch-app ...

  7. android 补丁包增量更新

    ●功能版本:增量更新是Google 4.1增加的新功能 ●功能背景: 现在的安卓Apk越来越大,而在此之前如果用户发现有新版本的话,需要重新把对应程序的新版本下载下来,有时候并不是重大更新,仅仅只是优 ...

  8. android 版本更新并启动,更新如此之快! 华为P20系列开启第二次安卓大版本升级...

    近期,EMUI正式开启对华为P20系列升级EMUI10内测招募.同时,根据此前EMUI公布信息,华为Mate10系列等多款较早机型也在升级EMUI10计划之中,将会在稍晚时候开启内测. 华为P20系列 ...

  9. android增量更新 腾讯,国内率先支持增量更新 腾讯应用宝3.1更快更省

    为了让Android用户更新升级已安装应用的速度更快,更省流量,近日腾讯应用宝继刚刚发布的全新3.0随心版后, V3.1版国内首家率先支持省流量"增量升级"新功能,只要用户安装了旧 ...

最新文章

  1. 立个flag,一个月之内把知识点整理完,放到博客
  2. 工作4年工资8K,还有什么理由不努力?
  3. 瞧瞧,这样的代码才叫 Pythonic
  4. Visual C# 2008+SQL Server 2005 数据库与网络开发-- 5.1 计算
  5. FISCO BCOS Transaction execution error合约执行失败原因
  6. ResNet网络结构代码该怎么看
  7. 离散数学 第一章 部分课后习题
  8. 微软漏洞导致SQL注入威胁
  9. 机器人鸣人是哪一集_博人传鸣人出场集数 博人传佐助哪几集出现过
  10. 让你的微信小程序对用户更加友好:上拉加载和下拉刷新就是关键
  11. 免费拥有个人云主机——AWS免费EC2套餐内容
  12. 【冬瓜哥画PPT】最完整的存储系统接口/协议/连接方式总结
  13. 联想笔记本电脑开机黑屏可能是什么原因
  14. 怎么挑选一部适合自己的全景相机?
  15. 【设计模式】外观模式代理模式中介者模式的区别
  16. android手机浏览器怎么查看网页源代码
  17. 教育培训app开发迅速成长的原因是?未来趋势如何?
  18. umi-request
  19. linux下彻底删除软件及配置文件
  20. 团体程序设计天梯赛-练习集L1-005 考试座位号 (15 分)c语言

热门文章

  1. 事件的独立和事件互不相容两个概念的区别
  2. 目前为止学习过的循环解析过程
  3. 什么是Android内核
  4. 微信分账:分账接收方列表格式错误
  5. java.lang.SecurityException: getDeviceId: The user 10158 does not meet the requirements to access de
  6. 嵩天python百度云盘_嵩字取名的含义
  7. Aquarius 水瓶
  8. android记账本登录界面,Android记账本开发(一):整体UI界面布局
  9. “使用区块链进行安全可信的电子医疗记录共享”外文翻译——2019年4月份
  10. Lanproxy 路径遍历漏洞 (CVE-2021-3019)