Android 的增量升级,不同热修复和热更新,它只是通过和老的 apk 对比,识别出与新 apk 之间的二进制差异,从而生成的补丁包(差量包); 工程连接:https://github.com/LillteZheng/ZDiffUpdate 首先,我们需要借助 bsdiff工具生成差量包。win 用户下载这个: 然后再通过 patch 与 老版本的apk对比,生成 差量包: 最后的结果如下: bsdiff 工具为 .c 的源代码,需要配合 bszip。(有些链接已经失效,通过我的github工程加载) 此时编译,会出现 bspatch.c 报错的问题,我们需要改变头文件的引入路径,注释掉默认的 <bzlib.h>,修改为: 新建一个 UpdateJni.java 类,引用 jni 库,并添加方法: 然后,编写 native-lib.cpp ,添加 diffUpdate() 方法,如下: 这样,我们的 C 层就编写完了。 回到 activity,在点击事件中,更新差量包: 由于解析差量包的过程是好事的,所以,我们放在 asynctask 中去更新。 效果如下: 既然功能已经完成了,下个工程还得重新搞一遍有点得不偿失,所以,从 debug 中,拿到已经有完整功能的 so: 参考:Android增量更新
一、介绍
这样的好处在于,不用全部下载所有的文件,比如一个游戏 1个多G,如果每次更新,都下载1个多G,相信这个游戏基本没人下,但是使用差量包,则需要几十或者几百兆,这样对用户来说,相对能接受些。
通过这篇文章,你将看到:
二、生成差量包
接着解压,文件如下:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200610114125794.png
接着,把老的 apk 和 新的 apk 放到相同目录下,并使用 cmd 执行以下命令,生成 patchbsdiff_win_exe>bsdiff.exe v1.0.apk v1.1.apk patch.patch
bspatch.exe v1.0.apk new.apk patch.patch
这样,v1.1.apk 与 new.apk 是相同的,这样,我们只需要把 new.apk 和 patch 上传到服务器,Android下载更新即可三、Android 增量更新(cmake)
导入源码:
然后打开 CMakeLists.txt 配置源码路径:# 配置路径,CMAKE_SOURCE_DIR 为CMakeLists.txt 的位置 file(GLOB bzip_source ${CMAKE_SOURCE_DIR}/bzip/*.c) add_library( # Sets the name of the library. native-lib # Sets the library as a shared library. SHARED #添加 bspatch 和 bzip 下的所有代码 bspatch.c ${bzip_source} # Provides a relative path to your source file(s). native-lib.cpp)
然后,再修改它的 main()函数名为 execute_update,方便后面我们的调用:
3.1 添加 Java 层调用方法
public class UpdateJni { static { System.loadLibrary("native-lib"); } /** * 升级方法 * * @param oldPath 老的apk 路径 * @param patch 对比生成的 patch 的路径 * @param newApkPath 新 apk 的路径 */ public static native void diffUpdate(String oldPath, String patch, String newApkPath); }
extern "C"{ //引入bspatch.c里的main方法 extern int execute_update(int argc,char * argv[]); } extern "C" JNIEXPORT void JNICALL Java_com_zhengsr_zdiffupdate_UpdateJni_diffUpdate(JNIEnv *env, jclass instance, jstring oldapk_, jstring patch_, jstring output_) { const char *oldapk = env->GetStringUTFChars(oldapk_, 0); const char *patch = env->GetStringUTFChars(patch_, 0); const char *output = env->GetStringUTFChars(output_, 0); int argc = 4; char *argv[4] ={"", const_cast<char *>(oldapk),const_cast<char *>(output),const_cast<char *>(patch)}; execute_update(argc,argv); env->ReleaseStringUTFChars(oldapk_, oldapk); env->ReleaseStringUTFChars(patch_, patch); env->ReleaseStringUTFChars(output_, output); }
public void test(View view) { /** * 使用请参考以下步骤 * 1、请先安装 v1.0.apk 看看效果,然后不要点击它的button,adb 命令参考:adb install -r v1.0.apk * 2、接着把new.apk 和 patch.patch push 到 sdcard,adb 命令参考:adb push patch.patch /sdcard/. * 3、运行软件,点击更新,即可看到 v1.0.apk 的背景被替换了 */ new UpdateTask().execute(); } class UpdateTask extends AsyncTask<Void,Void,File> { @Override protected File doInBackground(Void... voids) { //自己的apk 可以用这个 // String sourceDir = getApplicationInfo().sourceDir; String sourceDir = "/data/app/com.zhengsr.diffupdate-1/base.apk"; String patch = Environment.getExternalStorageDirectory().getAbsolutePath()+"/patch.patch"; String newApk = Environment.getExternalStorageDirectory().getAbsolutePath()+"/new.apk"; File file1 = new File(patch); File file2 = new File(newApk); long time = System.currentTimeMillis(); //差分包建议在子线程中运行,防止阻塞主线程 UpdateJni.diffUpdate(sourceDir,patch,newApk); return new File(newApk); } @Override protected void onPostExecute(File file) { super.onPostExecute(file); //2、安装 Intent i = new Intent(Intent.ACTION_VIEW); if(Build.VERSION.SDK_INT<Build.VERSION_CODES.N){ i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); i.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive"); }else { i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); String packageName = getApplication().getPackageName(); Uri contentUri = FileProvider.getUriForFile(MainActivity.this, packageName+ ".fileProvider", file); i.setDataAndType(contentUri,"application/vnd.android.package-archive"); } startActivity(i); } }
四、生成 so 工其他工程使用
新建一个cmake或ndk工程,把它放到 libs 中,并把 libnative-lib.so 命名成自己喜欢的,比如 libdiffUpdate.so:
然后再 build.gradle 中配置so库的位置:
接着,新建一个和 so 相同的包名,并把 UpdateJni 复制过去:
然后在 activity 中调用即可: class UpdateTask extends AsyncTask<Void,Void, File> { @Override protected File doInBackground(Void... voids) { //自己的apk 可以用这个 // String sourceDir = getApplicationInfo().sourceDir; String sourceDir = "/data/app/com.zhengsr.diffupdate-1/base.apk"; String patch = Environment.getExternalStorageDirectory().getAbsolutePath()+"/patch.patch"; String newApk = Environment.getExternalStorageDirectory().getAbsolutePath()+"/new.apk"; File file1 = new File(patch); File file2 = new File(newApk); //差分包建议在子线程中运行,防止阻塞主线程,这里是测试,所以没关系 long time = System.currentTimeMillis(); UpdateJni.diffUpdate(sourceDir,patch,newApk); return new File(newApk); } @Override protected void onPostExecute(File file) { super.onPostExecute(file); //2、安装 Intent i = new Intent(Intent.ACTION_VIEW); if(Build.VERSION.SDK_INT<Build.VERSION_CODES.N){ i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); i.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive"); }else { i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); String packageName = getApplication().getPackageName(); Uri contentUri = FileProvider.getUriForFile(MainActivity.this, packageName+ ".fileProvider", file); i.setDataAndType(contentUri,"application/vnd.android.package-archive"); } startActivity(i); } }
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算