步驟
1. java層靜態代碼塊:public static native String fun(String str);
2. 生成包名.類名.h頭文件:javah -classpath bin/class; android.jar -d jni 包名.類名
-classpath:把java代碼編譯成的.class的目錄
-d:輸出目錄
3. 創建.cpp文件:複製頭文件中的函數名再實現函數
4. mk文件:編譯腳本
LOCAL_MODULE := xxx // so名字
LOCAL_SRC_FILES := xxx // c代碼文件
5. 編譯:ndk-build
6. 導入so:System.loadLibrary("xxx");
7. 調用fun方法
java數據類型與native數據類型映射
除了void對應void,其它的都是在原類型上加j,比如int對應jint。
編寫native
1. Java類型轉native類型:在基本類型上加j
2. 函數指針:JNIEnv *env
3. 獲取java層傳過來的參數
a. 整型
b. 字符串轉換
// 生成指針
const char *p = (*env)->GetStringUTFChars(env, str, NULL); // 默認值NULL
// 釋放指針
(*env)->ReleaseStringUTFChars(env, str, p);
c. 數組拷貝
public static native int[] fun(int[] arr);
jint array[5];
// 數組複製
(*env)->GetIntArrayRegion(env, 0, 5, arr);// 從0到5
(*env)->SetIntArrayRegion(env, 0, 5, arr);
d. 數組指針
// 生成數組指針
jint *p = (*env)->GetIntArrayElements(env, arr, NULL);
// 數組長度
jsize len = GetArrayLength(env, arr);
(*env)->ReleaseStringUTFChars(env,arr,p);
4. 返回值給java層
a. 基本類型直接return數據
b. 數組需要NewxxxArray和SetxxxArrayRegion創建和賦值再return
c. 類或結構體:搜索類FindClass,獲取構造函數GetMethodID,創建實例NewObject,獲取成員屬性GetFieldID,設置屬性SetXXXField,最後return