我們來完成一個簡單的一B,沒那么多學術問題的Android增量更新的實現(xiàn)。
對,你沒看錯,今天沒有圖!因為太簡單了,什么?你不會NDK?看完了本篇你照樣可以實現(xiàn)增量更新!
首先我們先說下原理:
用戶安裝的APK和新版本APK存在著diff差異,通過diff工具可以生成一個新版本與舊版本差異的文件,將新版本和舊版本的差異合并,就成了新版本的APK。(不到100字)
我先介紹下我們的小伙伴
1.bsdiff 開源工具 http://www.daemonology.net/bsdiff/bsdiff-4.3.tar.gz
2.bzip2 開源工具 http://pan.baidu.com/s/1dE4Tr2p (已經(jīng)整理好!)
3.以上都是c源碼! 當然我已經(jīng)準備了一個在windows下編譯好的exe文件(你別問我為什么只給Windows的!因為我的是Windows系統(tǒng)!咋的?),到時候我們需要使用這個exe文件來生成差異包
http://pan.baidu.com/s/1nvyh8N3
實現(xiàn)步驟:
1.將你的老版本APK與新版本的APK放在同一個目錄下。
2.使用我網(wǎng)盤里面提供的dif工具來生成差異包
命令行走起:bsdiff.exe oldfile newfile patchfile ;老版本文件名,新版本文件名,差異文件名。對,回車之后等一會,生成了一個差異文件。
3.上NDK走起?。∣K如果你對NDK一點不懂那么請繼續(xù)看,如果你是神,那么請走開啦!)創(chuàng)建一個AndroidStudio項目,一定要勾選支持C++。
4.我們在cpp目錄下來創(chuàng)建一個c文件,叫 native-lib.c
5.將CMakeLists.txt中的native-lib.cpp修改為native-lib.c(沒記錯的話應該是在21行)
5.在Activity中創(chuàng)建一個native方法
public native void fkDiff(String oldFile,String newFile,String patchFile);
6.在上面的方法上面按下Alt+Enter 創(chuàng)建ndk的方法。
7.將bzip2的源代碼復制到cpp目錄下。
8.將bspatch.c中的所有代碼復制到 native-lib.c中的 fkDiff方法的上面(注意是上面,上面)
9.復制下面的頭文件列表覆蓋你的 native-lib.c中的頭文件列表(不要問為什么照做就是了)
#include "bzip2/bzlib.c"
#include "bzip2/crctable.c"
#include "bzip2/compress.c"
#include "bzip2/decompress.c"
#include "bzip2/randtable.c"
#include "bzip2/blocksort.c"
#include "bzip2/huffman.c"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <err.h>
#include <unistd.h>
#include <fcntl.h>
#include <jni.h>
10.在native-lib.c中搜索main函數(shù),將main函數(shù)改個名字,比如我改成 fkDiffPatch
11.讓我們來寫幾行NDK的代碼在你的fkDiff函數(shù)里面
char *oldFile =(char *) (*env)->GetStringUTFChars(env, oldFile_, 0);
char *newFile = (char *)(*env)->GetStringUTFChars(env, newFile_, 0);
char *patchFile = (char *)(*env)->GetStringUTFChars(env, patchFile_, 0);
char *comm = "bspatch";
int argc = 4;
char *argv[argc];
argv[0] = comm;
argv[1] = oldFile;
argv[2] = newFile;
argv[3] = patchFile;
/**
調用我們修改過名字的函數(shù)
如果這幾行代碼你看不懂那么我簡單說下,我們將main函數(shù)的命令行參數(shù)
傳進去而已,而且我們把main函數(shù)的名字改了啊!
**/
fkDiffPatch(argc,argv);
(*env)->ReleaseStringUTFChars(env, oldFile_, oldFile);
(*env)->ReleaseStringUTFChars(env, newFile_, newFile);
(*env)->ReleaseStringUTFChars(env, patchFile_, patchFile);
12.將我們生成的差異文件,push到sdcard中。在Activity中通過一個方法來獲取我們Apk的安裝路徑
public static String getApkFilePath(Context context, String packageName) {
try {
ApplicationInfo appInfo = context.getPackageManager()
.getApplicationInfo(packageName, 0);
return appInfo.sourceDir;
} catch (NameNotFoundException e) {
e.printStackTrace();
}
return null;
}
13.在Activity中調用fkDiff的native方法
fkDiff(getApkFilePath(Context,包名),合并后存儲新Apk的路徑,差異文件的路徑);
14.如果你能看到這里那么我還要告訴你一件事情,因為我們的diff合并是IO操作而且非常耗時,建議在線程中或者Service中去執(zhí)行。
15.當合并執(zhí)行完成后,調用安裝Apk的代碼即可(安裝我們合并好的Apk啊!啥?一般人都存在了sdcard里面??!別忘了添加sdcard的訪問權限??!)