JNI是什麼,我就不多作介紹,估狗一下應該資料就一堆,而且也會有很多教學。不過一般找到的教學都是透過Android Studio寫APP使用JNI的方式。卻找不到如果是AOSP開發者,如何撰寫JNI與配置Android.mk。
首先在你的上層JAVA的APP新增class介面來提供呼叫底層的API,其中System.loadLibrary的部分還可以不用先寫,不過寫了也不會影響產出header檔。
這裡宣告一個呼叫底層的函式,帶入整數值並回傳字串。
JniTest.java的內容如下:
package com.example.jni; public class JniTest { static { System.loadLibrary("libtest_jni"); } public native String passInt2JNIAndReturnString(int value); }
再來利用javah命令來生成c\c++的標頭檔,-d是header檔要產生在哪個路徑。
$./prebuilts/jdk/jdk9/linux-x86/bin/javah -v -jni -d ./vendor/yourpath/YourApp --class-path ./vendor/yourpath/YourApp/main/java com.example.jni.JniTest
|
執行後產生com_example_jni_JniTest.h,其內容如下,這個檔案不需要去修改他:
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class com_example_jni_JniTest */ #ifndef _Included_com_example_jni_JniTest #define _Included_com_example_jni_JniTest #ifdef __cplusplus extern "C" { #endif /* * Class: com_example_jni_JniTest * Method: passInt2JNIAndReturnString * Signature: (I)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_com_example_jni_JniTest_passInt2JNIAndReturnString (JNIEnv *, jobject, jint); #ifdef __cplusplus } #endif #endif
將這個header放到你的jni lib同層目錄下,撰寫你的程式碼,jniTest.cpp
#include <iostream> #include <log/log.h> #include "com_example_jni_JniTest.h" JNIEXPORT jstring JNICALL Java_com_example_jni_JniTest_passInt2JNIAndReturnString (JNIEnv *env, jobject, jint value) { ALOGD("your pass value:%d", value); return env->NewStringUTF(env, "You got it!!"); }
再來撰寫編譯你的jni lib的Android.mk
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := libtest_jni LOCAL_SRC_FILES := jniTest.cpp include $(BUILD_SHARED_LIBRARY)
Android.bp則如下:
cc_library_shared { name: "libtest_jni", srcs: [ "jniTest.cpp", ], }
回到你上層JAVA的APP,撰寫Android.mk,宣告要使用JNI的lib,只要加入這兩個宣告即可
LOCAL_REQUIRED_MODULES += libtest_jni #這個是說要先去編譯libtest_jni LOCAL_JNI_SHARED_LIBRARIES := libtest_jni #這個才是使用的宣告
Android.bp則一樣也是加入這兩個宣告:
required: ["libsound_jni"], jni_libs: ["libsound_jni"],
上層JAVA的APP呼叫方式,以下就寫個大概,就沒附完整的程式碼
import com.example.jni.TestJNI; JniTest jnitest = new JniTest(); Log.d("JNI", jnitest.passInt2JNIAndReturnString(3));
Place your comment