Android JNI 面面觀 2

JNI 是Java Native Interface。

Java Native Interface (JNI)標準成爲java平臺的一部分,
它允許Java代碼和其他語言寫的代碼進行交互。
JNI 是本地編程接口。它使得在 Java 虛擬機 (VM) 內部運行的 Java 代碼
能夠與用其它編程語言(如 C、C++ 和彙編語言)編寫的應用程序和庫進行互操作。

下面就是我在 Android 環境中一個Test JNI 的代碼。
1.
// TestNativeApi.java
// Native程序,編譯成jar包形式,被上層java應用調用。
// static 函數中調用 android System.loadLibrary() 來調用 .so 庫,
// loadLibrary()會判斷 .so庫的類型,如果是jni庫,則會調用 .so庫中的 JNI_OnLoad()函數來註冊jni interface.

package com.me.test;

import android.util.Log;

public final class TestNativeApi {

   static {
        try {
            System.loadLibrary("itest_jni");
        } catch (UnsatisfiedLinkError e) {
            Log.d("itest_jni", "itest jni library not found!");
        }
    }

    /**
     * This class is uninstantiable.
     */
    private TestNativeApi() {
        // This space intentionally left blank.
    }

    public native static int apiFunction();

}

// Android.mk for TestNativeApi.java
// 通過函數 BUILD_JAVA_LIBRARY 編譯成jar.

# Build com.me.test.jar
# ============================================================

test_dirs := /
./test/java/com/me/test

test_src_files := $(call all-java-files-under,$(cm_dirs))

# ====  the library  =========================================
include $(CLEAR_VARS)

LOCAL_SRC_FILES := $(test_src_files)

LOCAL_NO_STANDARD_LIBRARIES := true
LOCAL_JAVA_LIBRARIES := core framework

LOCAL_MODULE := com.me.test

include $(BUILD_JAVA_LIBRARY) 

2.
// TestInternalApi.cpp
// JNI interface class, JNI_OnLoad()函數在.so被load的時候調用
// JNI interface function中可以調用底層的 C++/C函數控制硬件等

#define LOG_TAG "itest_jni"
#include
#include
#include "jni.h"
#include "JNIHelp.h"
#include "android_runtime/AndroidRuntime.h"
#include "scm_dbus_utils.h"

#define INTERNALAPI_PKG_NAME                "com/me/test/TestNativeApi"

using namespace android;

static jint test_TestInterAPI_Func(JNIEnv* env, jobject clazz)
{
    jint ret = (jint)0;

    LOGD("call /"%s/"", __FUNCTION__);
    return ret;
}

/*
* JNI registration.
*/

static JNINativeMethod gTestInterApiMethods[] = {
    { "apiFunction", "()I", (void *)test_TestInterAPI_Func }
};

int register_com_me_test_TestInternalApiNative(JNIEnv *env)
{
    return AndroidRuntime::registerNativeMethods(env, INTERNALAPI_PKG_NAME, gTestInterApiMethods, NELEM(gTestInterApiMethods));
}

jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
    JNIEnv* env = NULL;
    jint result = -1;

    LOGD("TestInteralApi JNI loaded");

    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
        LOGE("GetEnv failed");
        goto bail;
    }
    assert(env != NULL);

    if (register_com_me_test_TestInternalApiNative(env) < 0) {
        LOGE("TestInternalApi native registration failed");
        goto bail;
    }

    result = JNI_VERSION_1_4;

bail:
    return result;
}

// Android.mk for TestInternalApi.cpp
// 通過函數 BUILD_SHARED_LIBRARY 編譯成 .so .

include $(CLEAR_VARS)

ifeq ($(TARGET_ARCH), arm)
LOCAL_CFLAGS += -DPACKED="__attribute__ ((packed))"
else
LOCAL_CFLAGS += -DPACKED=""
endif

LOCAL_SRC_FILES:= /
TestInternalApi.cpp

LOCAL_C_INCLUDES += /
$(JNI_H_INCLUDE)

LOCAL_SHARED_LIBRARIES := /
libandroid_runtime /
libnativehelper /
libcutils /
libutils /
libdvm

LOCAL_MODULE:= libitest_jni

include $(BUILD_SHARED_LIBRARY)

endif

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章