Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android studio下增量升級功能的NDK開發

Android studio下增量升級功能的NDK開發

編輯:關於Android編程

最近研究Android應用的增量升級功能,期間涉及到了NDK開發的內容,整理記錄在此。
先說幾個問題。一、NDK開發就是JNI開發啊,臥槽我原來都不知道啊,一直以為是兩個東西啊......二、關於開發環境,老的Eclipse版本要安裝的工具比較多,什麼NDK啊,cygwin啊什麼,AS(Android studio首字母,以下皆以AS代替)就簡單多了,直接裝一個NDK就可以了。貌似AS從1.3版本就可以不裝cygwin了,而我裝的是2.0版本的,更不需要裝。而且神奇的是,我安裝NDK的時候沒有翻牆,難道是因為google回歸了。安裝NDK的過程很簡單,點擊AS工具欄的\按鈕,在打開的Project structure窗口中選擇SDK Location選項,就可以看到NDK的安裝選項,沒有安裝的時候是可以選擇下載安裝或指定本地的安裝路徑的,但是我沒有截圖,只有一張安裝好之後的效果圖。

\然後開始開發步驟。以我開發的增量升級功能為例,順帶把增量升級講一下。增量升級的原理就不說了,百度一下就可以,直接說怎麼把增量升級合成到APP裡。一、先新建一個增量升級的工具類PatchUtil,定義一個本地方法patch。
package com.winter.updatedemo.utils;

public class PatchUtil {
    static{
        System.loadLibrary("patch");
    }

    public static native int patch(String oldApkPath, String newApkPath, String patchPath);
}

二、AS菜單欄,依次選擇Build->Make Project。執行完之後,把Project欄切換成project視角,依次打開app->build->intermediates->classes->debug->com->winter->updetedemo->utils,可以看到該文件夾下有一個PatchUtil.class文件。com->winter->updetedemo->utils這一路徑其實就是PatchUtil所在的包名,這個實際開發的時候請根據自己的包名找相應的路徑。三、然後我們用上面找到的.class文件,生成一個C/C++的頭文件。首先打開AS的terminal界面\然後依次輸入以下兩個命令 cd app\build\intermediates\classes\debug javah -jni com.winter.updatedemo.utils.PatchUtil,如下圖:\然後我們再看debug文件夾下,會 發現多出來一個com_winter_updatedemo_utils_PatchUtil.h文件,這就是我們需要的頭文件。\文件的內容我們打開看一下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include 
/* Header for class com_winter_updatedemo_utils_PatchUtil */

#ifndef _Included_com_winter_updatedemo_utils_PatchUtil
#define _Included_com_winter_updatedemo_utils_PatchUtil
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_winter_updatedemo_utils_PatchUtil
 * Method:    patch
 * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I
 */
JNIEXPORT jint JNICALL Java_com_winter_updatedemo_utils_PatchUtil_patch
  (JNIEnv *, jobject, jstring, jstring, jstring);

#ifdef __cplusplus
}
#endif
#endif
裡面聲明了一個函數JNIEXPORT jint JNICALL Java_com_winter_updatedemo_utils_PatchUtil_patch(JNIEnv *, jobject, jstring, jstring, jstring);這個函數就是PatchUtil類裡面本地方法的C實現。當然頭文件裡只是一個函數聲明,接下來我們就要實現這個函數。四、建立jni文件夾,把生成的頭文件拷貝進去。在app\src\main文件夾下右鍵,依次選擇New->Folder->JNI Folder,然後main文件夾下會生成一個新的文件夾jni,先把我們的頭文件拷進去。\五、接下來我們就需要用到bsdiff這個工具,bsdiff是一個開源的二進制差分工具,用來生成增量升級所需的差分包;與其相對應的bspatch則用來通過差分包合成新的APK包。對於客戶端而言,我們只需要完成bspatch的功能就可以了,bsdiff的功能一般由服務端實現。另外,bsdiff依賴bzip2,所以我們分別把兩個工具下載下來。bsdiff下載地址:bsdiff下載地址bzip2下載地址:bzip2下載地址bzip2解壓後又很多文件,但是我們用到的並不多,所以在jni文件夾下新建一個文件夾,把一下文件拷貝進去:\然後把bspatch.c文件考到jni文件夾下。然後做以下修改:1.找到第31行#include ,改成#include "bzip2/bzlib.h"2.在37行下面添加一行,新行內添加我們之前生成的頭文件 #include "com_winter_updatedemo_utils_PatchUtil.h"3.把main()函數的名稱修改掉,改成applypatch()或其他名稱4.在bspatch.c文件末尾添加以下函數:
JNIEXPORT jint JNICALL Java_com_winter_updatedemo_utils_PatchUtil_patch(JNIEnv *env,
		jobject obj, jstring old, jstring new, jstring patch) {

	char * ch[4];
	ch[0] = "bspatch";
	ch[1] = (char*) ((*env)->GetStringUTFChars(env, old, 0));
	ch[2] = (char*) ((*env)->GetStringUTFChars(env, new, 0));
	ch[3] = (char*) ((*env)->GetStringUTFChars(env, patch, 0));

	int ret = applypatch(4, ch);

	(*env)->ReleaseStringUTFChars(env, old, ch[1]);
	(*env)->ReleaseStringUTFChars(env, new, ch[2]);
	(*env)->ReleaseStringUTFChars(env, patch, ch[3]);

	return ret;
}
函數的名稱和參數與com_winter_updatedemo_utils_PatchUtil.h一致,其實就是PatchUtil裡patch()方法的C實現。
以上步驟完成後,我們再在jni文件夾下新建一個Android.mk文件,文件中的內容為:
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE     := patch
LOCAL_SRC_FILES  := bspatch.c

LOCAL_LDLIBS     := -lz -llog

include $(BUILD_SHARED_LIBRARY)
OK,jni文件夾下的工作做完了。六、最後修改下app文件夾下的build.gradle文件,在defaultConfig代碼塊中添加以下內容:
        ndk{
            moduleName "patch"
            ldLibs "z","log"
        }
這裡有一點需要注意,moduleName是最後編譯生成庫的名稱,當然,最終的.so文件會加一個前綴“lib”,例如上面的代碼,編譯後生成的.so文件的全名會是libpatch.so。另外,回頭看一下PatchUtil類中的static代碼塊,調用了加載庫文件的系統方法,其中的庫文件的名稱,與我們的moduleName是一致的,不要加任何前後綴。七、所有的工作都結束了,patch方法已經可以被調用了,在Activity裡起一個線程,調用PatchUtil.patch(),就可以進行APK包的合成了。八、bsdiff下載地址中,除了可以下載bsdiff的源碼,還可以下載windows環境下的.exe可執行文件,下載下來,我們就可以在本地手動生成差分包,而不需要依賴服務器了。九、Demo下載地址稍後奉上。十、疑問。聽說Android的源碼中也包含bsdiff的源碼,那麼Android有沒有原生的增量升級的接口呢?

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved