增量更新操作详解

增量更新操作详解

               ONE Goal , ONE Passion !

简介:


studio中操作步骤:

第一步:定义native方法

  • 直接copy两个工具类到项目中,如图1
    这里写图片描述

DiffUtils文件: 生成补丁


       public class DiffUtils {

        /**
         * 本地方法 比较路径为oldPath的apk与newPath的apk之间差异,并生成patch(补丁)包,存储于patchPath
         * 
         *
         * @return
         */
        public static native int genDiff(String oldApkPath, String newApkPath,
                                         String patchPath);
    }

PatchUtils文件: 合成apk

    public class PatchUtils {

        /**
         * native方法
         * 使用路径为oldApkPath的apk与路径为patchPath的补丁包,合成新的apk,并存储于newApkPath
         * @param oldApkPath
         * @param newApkPath
         * @param patchPath
         * @return
         */
        public static native int patch(String oldApkPath, String newApkPath,
                                       String patchPath);
    }

第二步:使用javah命令生成两个.h头文件

  • 找到源文件G:\andirodWorkspace\PatchDemo\app\src\main\java路径.
  • 右键shift + 右键. 打开命令行 输入javah命令

    javah com.fy.patchdemo.utils.PatchUtils
    
    javah com.fy.patchdemo.utils.DiffUtils
    

如图2:
这里写图片描述

第三步:新建jni目录

  1. 将生成两个.h头文件复制到jni目录(注意:jni和java文件在同一个目录)
  2. 将合成补丁的相关c文件导入jni目录中.如图3

这里写图片描述

  1. 编写我们定义的两个本地方法.

可是有点哥们说,不会写c代码啊! 表担心.两个c文件有现成的只要我们修改一下就行了.

特别注意:两个文件分别是diff.c patch.c文件
pathc.c文件
#include "com_fy_mypatch_apkutils_PatchUtils.h". 由于是直接copy的,所以这个头文件名要改成刚刚自己生成的

这里写图片描述
diff.c文件
#include “com_fy_mypatch_apkutils_DiffUtils.h” . 由于是直接copy的,所以这个头文件名要改成刚刚自己生成的

这里写图片描述

  • 4.还要修改两个文件pathcutils.c 和 diffutils.c文件.

两个文件中的方法名,一定要修改成相对应.h文件中生成的方法名.如图:

这里写图片描述


这里写图片描述

第四步:编译生成so文件

1.在gradle.properties最后添加一句:

  使用ndk开发可用
  android.useDeprecatedNdk=true

2.在build.gradle(modle)中配置:

  defaultConfig {
    applicationId "com.fy.patchdemo"
    minSdkVersion 15
    targetSdkVersion 23
    versionCode 1
    versionName "1.0"

      配置如下 :
    ndk{
        moduleName "diff"         //生成的so名字
        abiFilters "armeabi", "armeabi-v7a", "x86"  //输出指定三种abi体系结构下的so库。目前可有可无。
    }
}

3.build-Make Project生成相应的so文件.编译后在app-build-intermediates-ndk下查看生成的文件.此时已经有ndk文件了.

第五步:代码部分

  1. MainActivity:

        public class MainActivity extends AppCompatActivity {

        private String oldapk = "mnt/sdcard/old.apk"; //当前apk文件.
        private String newapk = "mnt/sdcard/new.apk";//将要更新的最新apk (一般不会出现在我们的android代码中,这里为了测试)
        private String pathapk = "mnt/sdcard/path.patch"; //old.apk 与 new.apk生成的补丁文件.   -----线下完成
        private String complexapk = "mnt/sdcard/newapk.apk";//合并后的apk (old.apk与path.patch文件生成最新apk)
        private ProgressDialog dialog;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            dialog = new ProgressDialog(this);
            dialog.setMessage("请稍后...");


        }


        static {
            System.loadLibrary("diff");
        }

        public void onclick(View view) {
            switch (view.getId()) {
                case R.id.add: //合成apk
                    //    dialog.show();
                    new Thread(new Runnable() {

                        @Override
                        public void run() {

                            // TODO Auto-generated method stub
                            PatchUtils.patch(oldapk, complexapk, pathapk);
                            runOnUiThread(new Runnable() {
                                public void run() {
                                    Toast.makeText(MainActivity.this, "补丁合成完毕", Toast.LENGTH_SHORT).show();
                                    dialog.dismiss();

                                    Intent intent = new Intent(Intent.ACTION_VIEW);
                                    intent.setDataAndType(Uri.parse("file:///sdcard/newapk.apk"),
                                            "application/vnd.android.package-archive");
                                    startActivity(intent);
                                }
                            });
                        }
                    }).start();

                    break;
                case R.id.diff://根据两个版本apk生成补丁
                    //       dialog.show();
                    new Thread(new Runnable() {

                        @Override
                        public void run() {

                            DiffUtils.genDiff(oldapk, newapk, pathapk);
                            runOnUiThread(new Runnable() {
                                public void run() {
                                    Toast.makeText(MainActivity.this, "生成补丁完成", Toast.LENGTH_SHORT).show();
                                    dialog.dismiss();
                                }
                            });
                        }
                    }).start();

                    break;
                default:
                    break;
            }
        }
    }

第6步:测试

如果是测试.生成补丁.要先生成一个不同版本apk放到sd卡下,注意apk名字要和代码中一致oldapk.

如果实际开发.后台生成补丁包的名字也要和代码一致:path. 代码可以修改

第6步:测试效果

这里写图片描述

——————实际开发————————-

  • 使用差分工具生成2个apk的差异文件(补丁).
    工具使用: 在bsdiff工具目录下,右键+shift 打开命令行. 执行命令.即可生成补丁.

这里写图片描述

  • 将生成的差异文件放到自己的服务器上
  • 用户点击省流量更新,下载差分文件(补丁),放到固定的位置(比如:/mnt/sdcard/path)
  • 将补丁与当前apk合并成新的apk.
//获取本应用的apk包路径
            public String getSelfApkPath() {
                List<ApplicationInfo> installList = getPackageManager().getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES);  
                for (int i = 0; i < installList.size(); i++) {  
                    ApplicationInfo info=installList.get(i);  
                    if(info.packageName.equals(getPackageName())){

                        return info.sourceDir;
                    }
                }
                return null;
            }
  • 将旧的应用删除.

附: 差分工具,以及项目demo
http://download.csdn.net/my

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值