NDK實戰(五)—— 增量更新(下)—— 合併差分包

Android平臺下合併patch差分包

一、添加文件

bzip2 的所有 .c.h 文件以及bspatch.c 複製到Android Studio 的 cpp 目錄下(記得修改main方法名,保證只有一個main入口)

二、在Cmake.txt中鏈接所有文件

使用

file(GLOB c_path src/main/cpp/*.c)

可以將所有文件添加爲一個 c_path 路徑變量
image

file(GLOB c_path src/main/cpp/bzip2/*.c)

add_library( # Sets the name of the library.
        bspacth-lib
        SHARED
        ${c_path}
        src/main/cpp/bspatch.c)

add_library( # Sets the name of the library.
        native-lib
        SHARED
        src/main/cpp/native-lib.c)

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

target_link_libraries( # Specifies the target library.
        native-lib
        bspacth-lib
        ${log-lib})

三、調用bspatch中的main方法

bspatch.c 中的 main 方法改名爲 bspatch_main

創建一個native方法並實現內容

 public static native int bsPatch(String oldPath, String newPath, String patchPath);
//bspatch已動態註冊

JNIEXPORT int JNICALL
bspatch(JNIEnv *env, jclass type, jstring jst_oldPath,
        jstring jst_newPath, jstring jst_patchPath) {

    char *oldPath = (char *) (*env)->GetStringUTFChars(env, jst_oldPath, NULL);
    char *newPath = (char *) (*env)->GetStringUTFChars(env, jst_newPath, NULL);
    char *patchPath = (char *) (*env)->GetStringUTFChars(env, jst_patchPath, NULL);

    int ret;

    int arg = 4;
    char *argv[4];
    argv[0] = "bspatch";
    argv[1] = oldPath;
    argv[2] = newPath;
    argv[3] = patchPath;
    ret = bspatch_main(arg, argv);
    
    (*env)->ReleaseStringUTFChars(env, jst_oldPath, oldPath);
    (*env)->ReleaseStringUTFChars(env, jst_newPath, newPath);
    (*env)->ReleaseStringUTFChars(env, jst_patchPath, patchPath);

    return ret;
}
    System.loadLibrary("native-lib")
    System.loadLibrary("bspatch-lib")
    //直接把apk和差分文件放入sdk進行合併測試
    val oldPath = SDK_CARD_PATH + File.separator + "appOld.apk"
    val newPath = SDK_CARD_PATH + File.separator + "appNew.apk"
    val patchPath = SDK_CARD_PATH + File.separator + "apk.patch"
        FileUtils.bspatch(oldPath,newPath,patchPath)

正常情況下apk安裝之後在系統中存在一份備份,應該用此備份作爲oldPath,patch文件也應該從服務端下載,這裏偷個懶。

    /**
     * 獲取已安裝Apk文件的源Apk文件
     * 如:/data/app/my.apk
     *
     * @param context
     * @param packageName
     * @return
     */
    public static String getSourceApkPath(Context context, String packageName) {
        if (TextUtils.isEmpty(packageName))
            return null;

        try {
            ApplicationInfo appInfo = context.getPackageManager()
                    .getApplicationInfo(packageName, 0);
            return appInfo.sourceDir;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

四、安裝合併之後的apk

    /**
     * 安裝Apk
     *
     * @param context
     * @param apkPath
     */
    public static void installApk(Context context, String apkPath) {

        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setDataAndType(Uri.parse("file://" + apkPath),
                "application/vnd.android.package-archive");

        context.startActivity(intent);
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章