韌館-LearnHouse

[Android]如何在AOSP下編譯JNI

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));
2022年7 月 posted by admin in 程式&軟體 and have No Comments

Place your comment

Please fill your data and comment below.
名稱:
信箱:
網站:
您的評論: