在Android Studio裡自定Android.mk和Application.mk內容來完成編譯NDK
首先要先建立兩個外部工具,好方便我們編譯的時候使用。
- 建立javah工具:
啟動Android Studio,然後在無開啟任何專案的情況下點選畫面中的Configure,如下圖紅框。
接著選擇settings,如下圖紅框所示。
如下圖選擇External Tools(紅框部分),然後按下黃色框框的+號鍵來新增Javah特定指令。
如下圖所示填入個別的值,Name、Group、Description任意你填,畫面上可以打勾的選項都打勾,Program要填你Jave SDK工具中javah.exe安裝的路徑位置,我這裡是安裝在C:\Program Files\Java\jdk1.8.0_25\bin\javah.exe。Parameters是要填入javah.exe要使用的參數,這裡直接填入-v -jni -d $ModuleFileDir$\src\main\jni $FileClass$,最後的Working directory就填入$SourcepathEntry$,以下列表3個值:
Program:C:\Program Files\Java\jdk1.8.0_25\bin\javah.exe
Parameters:-v -jni -d $ModuleFileDir$\src\main\jni $FileClass$
Working directory:$SourcepathEntry$
按下OK鍵存檔後繼續下一個NDK的設定。
- NDK設定
如下圖所示,可以打勾的都打勾,Name、Group、Description都自己填一個有意義的名稱,剩下的3個參數也如下列表,請自行複製使用即可。Program路徑是你NDK的目錄位置,因為Windows是利用cmd來叫出ndk編譯指令,因此檔名是ndk-build.cmd而不是ndk-build.exe,這點注意些。
Program:C:\ndk\ndk-build.cmd
Parameters:NDK_PROJECT_PATH=$ModuleFileDir$/build/intermediates/ndk NDK_LIBS_OUT=$ModuleFileDir$/src/main/jniLibs NDK_APPLICATION_MK=$ModuleFileDir$/src/main/jni/Application.mk APP_BUILD_SCRIPT=$ModuleFileDir$/src/main/jni/Android.mk V=1
Working directory:$SourcepathEntry$
一樣設定好後存檔就可以了。
接下來直接啟動一個新的專案,啟動完成後可以在如下圖看到我們剛剛設定的兩個外部工具,在[Tools]-->[ExtTools]下有兩個可以使用的工具(紅框部分)。
首先對畫面唯一的物件TextView給予id叫做TextView1,然後將專案切換到Project模式,如下圖紅框所示,接著在[app]à[src]—>[main]下按滑鼠右鍵新增一個jni目錄。
接著在MainActivity.java鍵入NDK的宣告碼(如下圖紅框):
static {
System.loadLibrary("JniDemo");
}
public native String getStringFromNative();
然後再鍵入呼叫c函數的程式碼(如下圖黃框):
TextView tmpView = (TextView) findViewById(R.id.TextView1);
tmpView.setText(getStringFromNative());
接下來將專案的位置用滑鼠點開到MainActivity.java檔案上,如下圖紅框,然後選用之前設定好的javah外部工具來自動產生.h宣告檔,.h檔案產生後會自動放在jni目錄下。
如果沒有問題會在下面訊息欄裡看到Process finished with exit code 0的訊息,如下圖紅框部分,.h檔位置和檔名如下圖黃框部分。
在jni目錄下分別新增3個檔案(下圖紅框部分),檔名為Android.mk、Application.mk、Hello.c,在Hello.c裡面鍵入C的原碼內容如下(下圖黃框部分):
#include <com_david_ndkdemo3_MainActivity.h>
JNIEXPORT jstring JNICALL Java_com_david_ndkdemo3_MainActivity_getStringFromNative
(JNIEnv * evn, jobject obj)
{
return (*evn)->NewStringUTF(evn,"Hello NKD demo");
}
Application.mk的內容我這裡只有指定支援的平台,語法如下:
APP_ABI := all
Android.mk我這裡是參照NDK的說明複製下來內容如下:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := Hello.c
LOCAL_LDLIBS += -llog
LOCAL_MODULE := JniDemo
LOCAL_CFLAGS :=
include $(BUILD_SHARED_LIBRARY)
接著開啟[app]à[ build.gradle]檔案(如下圖藍色框框),在裡面新增sourceSets.main.jni.srcDirs = [] (如下圖紅色框框),新增完成後別忘記要按右上角的Sync Now鍵(如下圖黃色框框)讓Gradle同步檢查語法一下。接著選擇[File]-->[Save All]把剛剛建的3個檔案的內容存檔下來。
最後選擇[Tools]à[Ndkbuild]呼叫外部NDK指令編譯一下c格式的檔案(如下圖紅色框框),執行無誤的話會看到最下面的訊息視窗出現Process finished with exit code 0的訊息(如下圖黃色框框),NDK會根據Application.mk裡面指定的支援平台編譯出來相關.so檔,檔案位置就在jniLibs目錄下依據平台自動分好目錄(如下圖藍色框框部分)。
最後按慣例,按下run app執行起app選擇一個模擬器讓app執行起來,如下圖就大功告成,這裡補充說明一下[ build.gradle]裡面的sourceSets.main.jni.srcDirs = []是讓gradle不要自動地去編譯c的檔案而改用人工編譯。