一 概念
NDK (Native Development Kit),
NDK是Google開發的一套開發和編譯工具集,可以生成動態鏈接庫
1.1 NDK與JNI的關係
JNI (Java Native Interface), java 本地化接口,可以通過JNI調用系統提供的API、操作系統(不管什麼系統底層都是使用C/C++作爲驅動的),Java在在運行時需要編譯成虛擬機可以運行的class字節碼,然後在由虛擬機編譯成機器碼,而C/C++可以直接編譯成機器碼,所以效率上Java不如C/C++,JNI測試Java和C/C++互調之間的橋樑
所以在Android開發中使用NDK 需要編寫c/c++代碼,而C/C++和Java的溝通橋樑是JNI,那可以說是NDK就是Android用於JNI開發的工具
1.2 手動創建JNI項目,生成SO文件
Android studio是支持創建JNI項目的,這樣省略了一些手動配置的麻煩,當然我們也需要知道在除了AS之外開發是怎麼去做的,也就是創建一個JNI項目的步驟是什麼?
- 在普通項目中首先創建一個包含native方法的Java類
public class JNIUtils {
public native int firstJniMethod(int first);
}
- 進到該文件目錄下,使用javah命令生成native的頭文件(Mac電腦Javah 可用javac XXX.java -h . 命令代替),同目錄生成.h文件
包名_類明.h
- main文件下創建jni 文件夾,將生成的頭文件拷貝到此,並創建.c文件,實現剛纔生成的文件中的方法
#include <com_kpa_myapplication_JNIUtils.h>
JNIEXPORT jint JNICALL Java_com_kpa_myapplication_JNIUtils_firstJniMethod(JNIEnv* env, jobject obj, jint first){
jint res = 10;
return res;
}
- 在JNI文件下創建Android.mk 和Application.mk
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := 名稱
LOCAL_SRC_FILES := Test.c
include $(BUILD_SHARED_LIBRARY)
Application.mk
APP_ABI := all
- 調用so庫
sourceSets {
main() {
jniLibs.srcDirs = ['src/main/libs']
jni.srcDirs = [] //屏蔽掉默認的jni編譯生成過程
}
}
// java
new JNIUtils().firstJniMethod(1)
在開發中我們其實不需要手動的去配置JNI的項目,一般開發時直接使用AS創建項目就可以了
1.3 AS開發NDK
AS 3.6.1 使用方法
1.新建項目
2. 選擇native C++ 模版
3. 選擇C++ support (一般選擇默認,也可以指定版本)
4. 運行項目
二、 目錄解析
2.1 目錄
與傳統項目區別,在main文件下多了一個cpp文件夾,這個文件下存放着開發的文件,是C++文件
extern "C" JNIEXPORT jstring JNICALL
Java_com_kpa_jnijavademo_MainActivity_stringFromJNI(
JNIEnv *env,
jobject obj/* this */) {
return env->NewStringUTF(hello.c_str());
}
開發時只需要以該文件爲基礎
2.2 第一個函數解析
Java_com_kpa_jnijavademo_MainActivity_stringFromJNI 對應的Java中的類的全目錄+ 方法名稱
Java 中
所屬類爲MainActivity
/**
* A native method that is implemented by the 'native-lib' native library,
* which is packaged with this application.
*/
public native String stringFromJNI();
Java_表示Java文件,
JNIEnv: 類型實際上是可以代表在native中的Java環境,操作Java代碼的方法都在裏面,
jobject obj
native 不是static 方法, obj就表示native方法的所屬類的實例
native 是static obj表示native方法的類的class對象實例