android ndk 开发之 在 框架层使用 jni

前面说过在android上实现jni调用有两种方式,在框架层实现,在应用程序 apk上实现。

 

在框架上实现:

需要在 java 源码中声明, 在C++代码中实现jni的各种方法,并注册到系统中。

jni的核心是jniNativeMethod 结构体,在jni.h中声明。

 

typedef struct {

 const char *name;  //jnj 函数的名称

 const cgar *signature; //参数以及返回值

 void * fnptr;             //对应的C/C++函数实现
 }JNINativeMethod;

 

比如 frameworks/base/core/jni 中的 android_util_Log.cpp 是对 frameworks/base/core/java/android/util 目录中的文件

Log.java的实现。

 

android_util_Log.cpp 定义了结构JNINativeMethod 实现的java方法,

 

/*
 * JNI registration.
 */
static JNINativeMethod gMethods[] = {
    /* name, signature, funcPtr */
    { "isLoggable",      "(Ljava/lang/String;I)Z", (void*) android_util_Log_isLoggable },
    { "println_native",  "(IILjava/lang/String;Ljava/lang/String;)I", (void*) android_util_Log_println_native },
};

 

gMethods[] 保存声明的方法,但要通过jni提供的注册函数注册到运行时库中,由系统启动时自动初始化,

 

int register_android_util_Log(JNIEnv* env)
{
    jclass clazz = env->FindClass("android/util/Log");

    if (clazz == NULL) {
        LOGE("Can't find android/util/Log");
        return -1;
    }
   
    levels.verbose = env->GetStaticIntField(clazz, env->GetStaticFieldID(clazz, "VERBOSE", "I"));
    levels.debug = env->GetStaticIntField(clazz, env->GetStaticFieldID(clazz, "DEBUG", "I"));
    levels.info = env->GetStaticIntField(clazz, env->GetStaticFieldID(clazz, "INFO", "I"));
    levels.warn = env->GetStaticIntField(clazz, env->GetStaticFieldID(clazz, "WARN", "I"));
    levels.error = env->GetStaticIntField(clazz, env->GetStaticFieldID(clazz, "ERROR", "I"));
    levels.assert = env->GetStaticIntField(clazz, env->GetStaticFieldID(clazz, "ASSERT", "I"));
               
    return AndroidRuntime::registerNativeMethods(env, "android/util/Log", gMethods, NELEM(gMethods));
}

 

registerNativeMethods 函数为系统提供的注册jni函数的方法。

 

在 frameworks/base/core/java/android/util 的Log.java文件中,要声明静态方法。

 

 

。。。。。。。。。。。。。。。。。。

 public static native boolean isLoggable(String tag, int level);
public static int w(String tag, Throwable tr) {
        return println_native(LOG_ID_MAIN, WARN, tag, getStackTraceString(tr));
    }

。。。。。

 

基本流程就是这样, 核心点为通过 registerNativeMethods 注册到系统中,实现绑定。

 

util log 因其简单,是一个学习的好例子,还有其他如 android_util_Binder.cpp ,android_util_process.cpp 可以深入学习。

你可能感兴趣的:(android,Framework)