JNI是什麼,我就不多作介紹,估狗一下應該資料就一堆,而且也會有很多教學。不過一般找到的教學都是透過Android Studio寫APP使用JNI的方式。卻找不到如果是AOSP開發者,如何撰寫JNI與配置Android.mk。

首先在你的上層JAVA的APP新增class介面來提供呼叫底層的API,其中System.loadLibrary的部分還可以不用先寫,不過寫了也不會影響產出header檔。
這裡宣告一個呼叫底層的函式,帶入整數值並回傳字串。
JniTest.java的內容如下:
[java]
package com.example.jni;

public class JniTest {

static {
System.loadLibrary("libtest_jni");
}

public native String passInt2JNIAndReturnString(int value);

}
[/java]

再來利用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,其內容如下,這個檔案不需要去修改他:
[c]
/* 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
[/c]

將這個header放到你的jni lib同層目錄下,撰寫你的程式碼,jniTest.cpp
[c]
#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!!");
}
[/c]

再來撰寫編譯你的jni lib的Android.mk
[c]
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libtest_jni
LOCAL_SRC_FILES := jniTest.cpp
include $(BUILD_SHARED_LIBRARY)
[/c]
Android.bp則如下:
[c]
cc_library_shared {
name: "libtest_jni",
srcs: [
"jniTest.cpp",
],
}
[/c]

回到你上層JAVA的APP,撰寫Android.mk,宣告要使用JNI的lib,只要加入這兩個宣告即可
[c]LOCAL_REQUIRED_MODULES += libtest_jni #這個是說要先去編譯libtest_jni
LOCAL_JNI_SHARED_LIBRARIES := libtest_jni #這個才是使用的宣告[/c]
Android.bp則一樣也是加入這兩個宣告:
[c]
required: ["libsound_jni"],
jni_libs: ["libsound_jni"],
[/c]

上層JAVA的APP呼叫方式,以下就寫個大概,就沒附完整的程式碼
[java]
import com.example.jni.TestJNI;

JniTest jnitest = new JniTest();
Log.d("JNI", jnitest.passInt2JNIAndReturnString(3));
[/java]

Leave a comment

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *