增量更新相关介绍
要想打造一款优秀的应用,必须要包含的功能之一应该就是应用内更新方案了 :)
本文将介绍如何在Android Studio3.6中布局属于自己的增量更新方案
如何导入
- 增量更新github代码 https://github.com/chaihuasong/AppSmartUpdate
(感谢itlwy作者贡献此代码,原代码链接 ) - 下载AppSmartUpdate模块后导入到AndroidStudio中,可以根据需要进行修改和Debug
- 使用AndroidStudio编译AppSmartUpdate模块:Build -> Make Module 'smartupdate’
- 编译成功后,会在如下路径生成smartupdate-debug.aar 文件:
AppSmartUpdate/smartupdate/build/outputs/aar/smartupdate-debug.aar
- 得到aar文件后,将此重命名未smartupdate.aar,考到目标工程项目的app/libs目录下
- 在AndroidStudio app build.gradle中新增如下配置
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation fileTree(include: ['*.aar'], dir: 'libs')
implementation 'com.squareup.okhttp3:okhttp:3.11.0'
implementation 'com.google.code.gson:gson:2.8.5'
api 'com.daimajia.numberprogressbar:library:1.4@aar'
}
- AndroidManifest中新增权限
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
- 调用方法
添加在自定义的Application类中:
import android.app.Application;
import com.chs.smartupdate.Config;
import com.chs.smartupdate.UpdateManager;
public class Mypplication extends Application {
@Override
public void onCreate() {
super.onCreate();
//推荐在Application中初始化
Config config = new Config.Builder()
.isDebug(true)
.build(this);
UpdateManager.getInstance().init(config);
}
}
在AndroidManifest.xml中添加此Application
<application
android:name=".MyApplication"/>
- Activity/Fragment 调用
import com.chs.smartupdate.UpdateManager;
import com.chs.smartupdate.api.IUpdateCallback;
import com.chs.smartupdate.utils.IntentUtils;
private static final String MANIFESTJSONURL = "https://raw.githubusercontent.com/chaihuasong/htz-updater/master/resource/UpdateManifest.json";
final IUpdateCallback mCallback = new IUpdateCallback() {
@Override
public void noNewApp() {
Log.d("smart_update", "onNewApp");
Toast.makeText(mAppCompatActivity, "当前已是最新版本!", Toast.LENGTH_SHORT).show();
}
@Override
public void beforeUpdate() {
Log.d("smart_update", "beforeUpdate");
}
@Override
public void onProgress(int i, long l, int i1, int i2) {
Log.d("smart_update", "onProgress:" + i);
}
@Override
public void onCompleted() {
Log.d("smart_update", "onCompleted");
}
@Override
public void onError(String s) {
Log.d("smart_update", "onError:" + s);
Toast.makeText(getContext(), "错误:" + s, Toast.LENGTH_SHORT).show();
}
@Override
public void onCancelUpdate() {
Log.d("smart_update", "onCancelUpdate");
}
@Override
public void onBackgroundTrigger() {
Log.d("smart_update", "onBackgroundTrigger");
}
};
UpdateManager.getInstance().update(mAppCompatActivity, MANIFESTJSONURL, mCallback);
为了解决需要开启未知应用安装功能后再能安装的问题,这里需要重写一下onActivityResult函数
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.d("smart_update", "onActivityResult requestCode:" + requestCode + " resultCode:" + resultCode);
if (resultCode == Activity.RESULT_OK && requestCode == IntentUtils.INSTALL_PERMISS_CODE) {
//must call after UpdateManager update method
UpdateManager.getInstance().installApk(UpdateManager.getInstance().getApkPath());
}
}
如果是fragment的话,需要重写Activity的onActivityResult方法,否则无法调用到fragment的onActivityResult方法:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d("smart_update", "activity onActivityResult requestCode:" + requestCode + " resultCode:" + resultCode);
super.onActivityResult(requestCode, resultCode, data);
for (Fragment fragment : mlist) {
fragment.onActivityResult(requestCode, resultCode, data);
}
}
其中包含的MANIFESTJSONURL很重要,一个类似的配置json文件如下
{
"minVersion": "100", // app最低支持的版本代码(包含),低于此数值的app将强制更新
"minAllowPatchVersion": "100", // 最低支持的差分版本(包含),低于此数值的app将采取全量更新,否则采用差量
"newVersion": "101", // 当前最新版本代码
"tip": "这是第一个测试更新", // 更新提示
"size": 2556755, // 最新apk文件大小
"apkURL": "https://github.com/chaihuasong/test/tree/master/resource/app/app_new.apk", // 最新apk url地址
"hash": "a583e488c886c1b10e804d758109ec8a", // 最新apk文件的md5值
"patchInfo": { // 差分包信息
"v100": { // v100表示-版本代码100的apk需要下载的差分包
"patchURL": "https://github.com/chaihuasong/test/tree/master/resource/app/v100/diff.patch", //差分包地址
"tip": "测试的提示", // 提示
"hash": "a583e488c886c1b10e804d758109ec8a", // 合成后apk(即版本代码101)的文件md5值
"size": 40272 // 差分包大小
}
}
}
如何制作patch文件
- 需要linux 环境下执行
- 请点击此处下载bsdiff工具
- 解压后有使用说明
//制作new apk和old apk的查分文件diff.patch
./bsdiff app_old.apk app_new.apk diff.patch
//查看制作新的apk的md5值
md5sum app_new.apk
//使用diff.patch重新合成app_diff_patch.apk,app_diff_patch.apk的md5值跟app_new.apk一致
./bspatch app_old.apk app_diff_patch.apk ./diff.patch
//查看生成app_diff_patch.apk的md5值
md5sum app_diff_patch.apk
将生成的值填入到如上json文件中保存,做为测试代码,可以上传至github中
至此,基本过程就完成了,后续待补充。