Android Studio NDK開發(fā)步驟
用Android Studio進(jìn)行NDK開發(fā)比Eclipse更加靈活方便。
環(huán)境搭建
下載安裝Android NDK
地址:http://developer.android.com/sdk/ndk/index.html
Android Studio里面設(shè)置NDK路徑:

新建NDKDemo項(xiàng)目

新建一個(gè)類JniUtils用來實(shí)現(xiàn)native方法:
public class JniUtils {
public static native String getStringFromC();
}
Rebuild Project

此時(shí)會(huì)生成JniUtils.class

然后在命令窗口定位到classes\debug目錄下,執(zhí)行命令(注意區(qū)分大小寫)
javah -jni com.smile.sample.ndkdemo.JniUtils
此時(shí)會(huì)在debug目錄下生成文件 com_smile_sample_ndkdemo_JniUtils.h
在app模塊下,新建jni目錄,并把頭文件放到這個(gè)目錄下。

新建一個(gè)cpp文件JniUtils.cpp來實(shí)現(xiàn)方法。
此時(shí)需要做幾個(gè)操作:
- 下載和配置NDK路徑
- 修改build.gradle配置,在defaultConfig里面新增一下代碼
ndk {
moduleName "JniDemo"
abiFilters "armeabi", "armeabi-v7a", "x86"
}
- 在gradle.properties里面配置
android.useDeprecatedNdk=true
- Jni目錄下,新建一個(gè)cpp的空文件
解決方案:
這是NDK在Windows下一個(gè)bug,當(dāng)只編譯一個(gè)文件時(shí)出現(xiàn),解決方法就是再添加一個(gè)空的文件即可。
原文見http://ph0b.com/android-studio-gradle-and-ndk-integration/:
- 在JniUtils.cpp里面輸入以下代碼:
#include "com_smile_sample_ndkdemo_JniUtils.h"
JNIEXPORT jstring JNICALL Java_com_smile_sample_ndkdemo_JniUtils_getStringFromC
(JNIEnv * env, jclass obj){
return env->NewStringUTF("這里是C++代碼");
}
Rebuild Project生成.so文件

在JniUtils里面,加入加載so文件代碼。
static {
System.loadLibrary("JniDemo");
}
到此,代碼已經(jīng)編寫完成,運(yùn)行程序看看吧。運(yùn)行

在app\main下新建jniLibs目錄,然后把剛才生成的.so文件夾拷貝到這里,刪除jni目錄,Rebuild Project 運(yùn)行依然正常。
常見問題
- 如果是JniUtils.c,則代碼不一樣;
#include "com_smile_sample_ndkdemo_JniUtils.h"
JNIEXPORT jstring JNICALL Java_com_smile_sample_ndkdemo_JniUtils_getStringFromC
(JNIEnv * env, jclass obj){
return (*env)->NewStringUTF(env, "這里是C代碼");
}
-
編譯錯(cuò)誤no rule to make target
Paste_Image.png
解決辦法:
這是因?yàn)槲覀僯ni目錄下只有個(gè)cpp文件,新建一個(gè)空的cpp文件即可。這個(gè)是NDK在Windows下的一個(gè)bug. -
編譯錯(cuò)誤Error: NDK integration is deprecated in the current plugin.
Paste_Image.png
解決辦法:
在gradle.properties里面新增
android.useDeprecatedNdk=true
- 運(yùn)行錯(cuò)誤java.lang.UnsatisfiedLinkError: Native method not found
找不到native方法,檢查下是否忘記加System.loadLibrary或者庫名寫錯(cuò)了。
庫名稱要跟gradle里面配置的一致。
static {
System.loadLibrary("JniDemo");
}
ndk {
moduleName "JniDemo"
abiFilters "armeabi", "armeabi-v7a", "x86"
}
- 無法使用stl庫,找不到<string>路徑, 設(shè)置ndk支持stl
ndk {
moduleName "soundtouch"
//stl "stlport_shared"
ldLibs "log", "z", "m"
//cFlags "-Wall -Wextra -I " + projectDir + "/src/main/jni/include"
abiFilters "armeabi", "armeabi-v7a", "x86"
stl "stlport_static" // 支持stl
cFlags "-fexceptions" // 支持exception
}
- 解決NDK出現(xiàn)error: exception handling disabled, use -fexceptions to enable的問題
cFlags "-fexceptions" // 支持exception
當(dāng)然,目前AS已經(jīng)更好的支持NDK開發(fā)了,可以自動(dòng)幫我們生成c++方法。
參考:AndroidStudio支持新的NDK的操作使用

