现在的位置: 首页 > 综合 > 正文

Android JNI 面面观 2

2013年11月17日 ⁄ 综合 ⁄ 共 2829字 ⁄ 字号 评论关闭

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)         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

抱歉!评论已关闭.