Android 增量更新demo

增量更新:通过bsdiff.exe工具将oldapk和newapk进行比较并生成一个差分包patch,用户需要更新时只需要下载差分包到本地通过                     native方法将oldapk和差分包patch进行合并,生成newapk。                     

所需资源下载: https://download.youkuaiyun.com/download/qq_29651765/10804911

开始写Demo:新建Android项目 并勾选

1.进入项目打开cpp文件夹,把下载的bspatch.c复制到cpp文件夹内。

2.然后打开下载的文件bsdiff and bzip2------>  bzip2-1.0.6 ---> bzip2-1.0.6----->Makefile

3.这里是ndk合并差分包所需要的资源文件,这些资源文件在Makefile同目录中,在cpp文件下新建bzip包,把这些资源文件复制到项目cpp/bzip文件夹下。

4.打开app的build.gradle文件指定保留的so库

 cmake {
    cppFlags ""
    //只保留指定的so库
    abiFilters 'armeabi-v7a'
 }

   到这里准备工作基本做完。

5.配置ndk文件

   1).打开CMakeLists.txt 配置如下(红色字体为需要添加的地方)

      

cmake_minimum_required(VERSION 3.4.1)
#加载cpp文件夹下的所有c文件
file(GLOB bzip_source src/main/cpp/bzip/*.c)



add_library( # Sets the name of the library.
             native-lib

             # Sets the library as a shared library.
             SHARED

             # Provides a relative path to your source file(s).
             src/main/cpp/native-lib.cpp
             src/main/cpp/bspatch.c
             ${bzip_source}
             )

include_directories(src/main/cpp/bzip)

find_library( # Sets the name of the path variable.
              log-lib

              # Specifies the name of the NDK library that
              # you want CMake to locate.
              log )



target_link_libraries( # Specifies the target library.
                       native-lib

                       # Links the target library to the log library
                       # included in the NDK.
                       ${log-lib} )

  2).在MainActivity中新建native方法用于合成newapk。

   native void bspatch(String oldapk, String patch, String outapk);

 3).在natvie-lib.cpp文件中创建对应的jni方法

  #include <jni.h>
  #include <string>

  extern "C"{
      extern int bspatch_main(int argc,char * argv[]);
  }


  extern "C"
  JNIEXPORT void JNICALL
  Java_app_zengliang_com_zengliang_MainActivity_bspatch(JNIEnv *env,jobject instance,jstring oldapk_,jstring      patch_,jstring outapk_){
    const  char *oldapk=env->GetStringUTFChars(oldapk_,0);
    const  char *patch=env->GetStringUTFChars(patch_,0);
    const char *outapk=env->GetStringUTFChars(outapk_,0);
    char *argv[]={"",const_cast<char *>(oldapk),const_cast<char *>(outapk),const_cast<char *>(patch)};
    //调用bspatch.c的main方法进行合成newapk(为了不和其他c文件main方法名字冲突这里改为bspatch_main,同时需要在bspatch.c               中修改为bspatch_main)
    bspatch_main(4,argv);
    env->ReleaseStringUTFChars(oldapk_,oldapk);
    env->ReleaseStringUTFChars(patch_,patch);
    env->ReleaseStringUTFChars(outapk_,outapk);
  }

 6.编写MainActivity中合成方法。

 1).(首先添加sdcard读写权限)

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
public void update(View view) {
    new AsyncTask<Void, Void, File>() {
        @Override
        protected File doInBackground(Void... voids) {
            //获取路径原app
            String oldapk = getApplication().getApplicationInfo().sourceDir;
            //获取差分包路径
            String patch = getPath("patch");
            //生成的新app的路径
            String outapk = getPath("new.apk");
            bspatch(oldapk, patch, outapk);
            return new File(outapk);
        }

        @Override
        protected void onPostExecute(File file) {
            super.onPostExecute(file);
            //安装app
             installApk(file);
        }
    }.execute();
}

//获取某文件在sd卡的绝对路径
private String getPath(String name) {
    return new File(Environment.getExternalStorageDirectory(), name).getAbsolutePath();
}

private void installApk(File newapk) {
    if (!newapk.exists()) {
        return;
    }
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        Uri fileUri = UriParseUtils.getUriFromeFile(this, newapk);
        intent.setDataAndType(fileUri, "application/vnd.android.package-archive");
    } else {
        intent.setDataAndType(Uri.fromFile(newapk), "application/vnd.android.package-archive");
    }
    startActivity(intent);
}

native void bspatch(String oldapk, String patch, String outapk);

2).在AndroidManifest中添加如下代码(为了适配7.0+文件权限)

   

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="xxx.xxx.fileprovider"(这里修改为自己的包名)
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/provider_paths" />
</provider>

provider_paths.xml 标记为sdcard根目录

<?xml version="1.0" encoding="utf-8"?>
<path>
    <root-path name="root_path" path="."/>
</path>

代码编写完成

测试:

1.首先rebuild出一个1.0版本的app。

2.修改版本号为2.0并在MainActivty中添加一个背景图片(用于区分是否成功合成),然后rebuild出一个2.0版本的app。

3.在下载的资源文件中打开含有bsdiff.exe文件的文件夹并把rebuild的两个apk复制过来,cmd打开命令行运行命令

   bsdiff.exe app-1.apk app-2.apk patch 点击回车会发现此文件夹下多出了个patch文件。

4.把patch文件复制到sdcard根目录(开发中需要把patch从服务器下载到sdcard进行合并,这里只做演示),   安装app1

   打开点击更新调用update(View view)方法,就会进入安装页面。

 

注:本人对ndk也不太熟悉,只是讲了下大概如何配置,就当笔记看了,见笑。

 

 

 

     

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值