Android带你实现增量更新!

作者:itfitness

链接:

https://www.jianshu.com/p/828d760ec54b


其实差分不仅可以用于应用增量更新,相反凡是下发的资源,其实都可以利用增量更新来节省流量,降低下载耗时,从而提升用户体验。


目录


Android带你实现增量更新!


1

前期准备


1.工具下载

这里我把需要用到的代码和工具都整理了一下放到了一起:

https://www.aliyundrive.com/s/ALCxbGeWY2o


Android带你实现增量更新!


bzip2:是bsdiff依赖的一个库,这里我只存放了需要用到的文件,完整版的下载地址为:

https://sourceforge.net/projects/bzip2/files/latest/download



bsdiff-win:是编译好的Windows平台下的可执行文件,可以在Windows平台生成差异文件和合并文件。

bsdiff-source:是bsdiff的源码,它的官网为:

http://www.daemonology.net/bsdiff/


2.工具的使用方法

只需要在工具所在的目录打开命令行窗口。


Android带你实现增量更新!


然后输入命令即可:


#生成差异文件命令
bsdiff [旧文件] [新文件] [差异文件]
#合并文件命令
bspatch [旧文件] [新文件] [差异文件]


例如我这创建两个文本文件old.txt和new.txt。


Android带你实现增量更新!

old.txt


Android带你实现增量更新!

new.txt


然后我可以利用bsdiff命令生成差异文件。


Android带你实现增量更新!


Android带你实现增量更新!


这个时候我再利用bspatch命令,将old.txt和patch文件合成new2.txt。


Android带你实现增量更新!


Android带你实现增量更新!


我们打开new2.txt发现与new.txt是一样的。


Android带你实现增量更新!

new2.txt


2

原理讲解


实现原理其实就是将新APK文件与旧APK文件进行对比,得出一个差异文件,然后用户端下载这个差异文件与手机上的那个旧APK文件进行合并即可得到与新的APK文件一样的文件,然后再安装这个新APK即可实现增量更新,如下图所示。

Android带你实现增量更新!


3

具体实现


1.集成bspatch到项目

由于Android端只需要合并文件所以我们只需要集成bspatch即可,我们将bsdiff-source/bsdiff-4.3文件夹中的bspatch.c文件拷贝到cpp目录,然后将bzip2文件夹下的文件拷贝到cpp下的bzip(新建的目录)目录下。


Android带你实现增量更新!


此外我们还要对bspatch.c进行修改,我们在文件顶部加入bzip2的引用。


/** 导入bzip2的引用*/
#include "bzip/bzlib.c"
#include "bzip/crctable.c"
#include "bzip/compress.c"
#include "bzip/decompress.c"
#include "bzip/randtable.c"
#include "bzip/blocksort.c"
#include "bzip/huffman.c"


Android带你实现增量更新!


否则的话你运行项目的时候可能会报如下错误:


Android带你实现增量更新!


然后我们还需要新建bspatch.h放到bzip文件夹下,这样做目的是为了可以在native-lib.cpp文件中使用main方法。(注意:这里的main方法并不是入口函数,就是一个执行命令的普通函数)


Android带你实现增量更新!


bspatch.h文件如下:


#ifndef INCREMENTUPDATEDEMO_BSPATCH_H
#define INCREMENTUPDATEDEMO_BSPATCH_H
int main(int argc,char * argv[]);
#endif //INCREMENTUPDATEDEMO_BSPATCH_H


然后在bspatch.c中引入bspatch.h头文件。


Android带你实现增量更新!


接下来我们需要配置下CMakeLists.txt文件将bzip下的c文件和.h头文件链接到项目。


cmake_minimum_required(VERSION 3.10.2)

project("incrementupdatedemo")
#定义一个全局变量包含了所有要编译的C文件
file(GLOB BZIP bzip/*.c)
#导入头文件
include_directories(bzip)
add_library( # Sets the name of the library.
             native-lib
             SHARED
             native-lib.cpp
             #将bzip下的.c文件添加到library
             BZIP)
find_library( # Sets the name of the path variable.
              log-lib
              log )
target_link_libraries( # Specifies the target library.
                       native-lib
                       ${log-lib} )


2.创建JNI方法

创建PatchUtil工具类,创建合并文件的JNI方法。


public class PatchUtil {
    static {
        System.loadLibrary("native-lib");
    }
    /**
     * 合并APK文件
     * @param oldApkFile 旧APK文件路径
     * @param newApkFile 新APK文件路径(存储生成的APK的路径)
     * @param patchFile 差异文件
     */

    public native static void patchAPK(String oldApkFile,String newApkFile,String patchFile);
}


C++实现JNI方法。


#include <jni.h>
#include <string>
#include "bspatch.h"
extern "C"
JNIEXPORT void JNICALL
Java_com_itfitness_incrementupdatedemo_PatchUtil_patchAPK(JNIEnv *env, jclass clazz,
                                                          jstring old_apk_file,
                                                          jstring new_apk_file,
                                                          jstring patch_file)
 
{
    int argc = 4;
    char * argv[argc];
    argv[0] = "bspatch";
    argv[1] = (char*) (env->GetStringUTFChars(old_apk_file, 0));
    argv[2] = (char*) (env->GetStringUTFChars(new_apk_file, 0));
    argv[3] = (char*) (env->GetStringUTFChars(patch_file, 0));

    //调用合并的方法
    main(argc, argv);

    env->ReleaseStringUTFChars(old_apk_file, argv[1]);
    env->ReleaseStringUTFChars(new_apk_file, argv[2]);
    env->ReleaseStringUTFChars(patch_file, argv[3]);
}


3.Activity中增加合成的调用。

public class MainActivity extends AppCompatActivity {
    private TextView tv_version;
    private Button bt_update;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv_version = findViewById(R.id.tv_version);
        bt_update = findViewById(R.id.bt_update);
        tv_version.setText("1.0");
        bt_update.setOnClickListener(v->{
            new Thread(() -> {
                File oldApkFile = new File(getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "old.apk");
                File newApkFile = new File(getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "new.apk");
                File patchFile = new File(getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "patch");
                PatchUtil.patchAPK(oldApkFile.getAbsolutePath(),newApkFile.getAbsolutePath(),patchFile.getAbsolutePath());
                //安装APK
                AppUtils.installApp(newApkFile);
            }).start();
        });
    }
}

4.编译生成旧APK

这里我们在1.0版本(旧版本)中展示当前应用的版本号,如下所示:


Android带你实现增量更新!


然后我们取出编译生成的APK命名为old.apk。


Android带你实现增量更新!


5.编译生成新APK

然后我们将版本号改为2.0并且在按钮下增加一张图片。


Android带你实现增量更新!


我们将其命名为new.apk。



Android带你实现增量更新!


6.使用bsdiff生成差异文件

使用bsdiff生成差异文件。


Android带你实现增量更新!


Android带你实现增量更新!


7.使用bspatch合并文件

接下来我们装回旧版然后将old.apk和patch放到SD卡中,当然真实环境的patch文件是通过网络下载得到的,这里我们模拟已经下载完毕了。


Android带你实现增量更新!


点击按钮,会发现Download文件夹下出现了一个new.apk文件。


Android带你实现增量更新!


然后我们通过代码将new.apk安装到手机上。


Android带你实现增量更新!


案例源码

https://Gitee.com/itfitness/increment-update



版权申明:内容来源网络,版权归原创者所有。除非无法确认,都会标明作者及出处,如有侵权,烦请告知,我们会立即删除并致歉!

原文始发于微信公众号(互联网程序员):Android带你实现增量更新!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由半码博客整理,本文链接:https://www.bmabk.com/index.php/post/24174.html

(0)

相关推荐

发表回复

登录后才能评论
半码博客——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!