分享

Android JNI 通过JNI_Onload注册方法的过程

 开花结果 2011-05-11

简单的Jni 例子都是映射模式,及对应的Jni 的c/c++ 实现需要,被java的函数命名规则限制死,为了解决这类毛病,引入的JNI_OnLoad这类方法。
jint JNI_OnLoad(JavaVM* vm, void* reserved)
该方法在Jni so 被加载时调用
以下提供一个实例:
C方面
#include <string.h>
#include <stdio.h>
#include "utils/Log.h"
#include <unistd.h>
#include <assert.h>
 
#include "jni.h"
#include "JNIHelp.h"
#ifndef LOG_TAG
#define LOG_TAG "venus"
#endif
 
 
static void setTitle(JNIEnv* env, jobject thiz, jstring str)
{
    char buf[256];
    const char *strUTF = env->GetStringUTFChars(str, 0);
 
    snprintf(buf, sizeof(buf), "venus set Title: %s\n", strUTF);
    env->ReleaseStringUTFChars(str, strUTF);
 
    jstring title = env->NewStringUTF(buf);
    jclass cls = env->GetObjectClass(thiz);
 
    //jmethodID mid;
    //mid = env->GetMethodID(cls, "setTitle", "(Ljava/lang/String;)V");
    //env->CallVoidMethod(thiz, mid, str);
 
    jfieldID fid;
    fid = env->GetFieldID(cls, "mTitle", "Ljava/lang/String;");
    env->SetObjectField(thiz, fid, title);
    env->ReleaseStringUTFChars(title, buf);
 
    LOGD("--------------setTitle------------>>>>%s\n", buf);
}
 
 
 
static jint getSum(JNIEnv* env, jobject thiz, jint num1, jint num2)
{
    int result;
 
    result = num1 + num2;
    LOGD("--------------getSum------------>>>>%d\n", result);
    return result;
}
 
 
 
static const JNINativeMethod gMethods[] = {
    {"setTitle", "(Ljava/lang/String;)V", (void *)setTitle},
    {"getSum", "(II)I", (void *)getSum},
 
};
 
static int registerMethods(JNIEnv* env)
{
    jclass clazz;
    static const char* const kClassName =  "com/android/jni_second/JNI";
 
    /* look up the class */
    clazz = env->FindClass(kClassName);
 
    if (clazz == NULL) {
        LOGE("Can't find class %s\n", kClassName);
        return -1;
    }
 
    /* register all the methods */
    if (env->RegisterNatives(clazz, gMethods, sizeof(gMethods) / sizeof(gMethods[0])) != JNI_OK)
    {
        LOGE("Failed registering methods for %s\n", kClassName);
        return -1;
    }
 
    /* fill out the rest of the ID cache */
    return 0;
}
 
 
/*
 * This is called by the VM when the shared library is first loaded.
 */
jint JNI_OnLoad(JavaVM* vm, void* reserved) {
    JNIEnv* env = NULL;
    jint result = -1;
 LOGI("--------------JNI_OnLoad---------------------");
 
    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK)
    {
        LOGE("ERROR: GetEnv failed\n");
        goto fail;
    }
 
    assert(env != NULL);
 
    if (registerMethods(env) != 0)
    {
        LOGE("ERROR: PlatformLibrary native registration failed\n");
        goto fail;
    }
 
    /* success -- return valid version number */
    result = JNI_VERSION_1_4;
fail:
    return result;
}
Java方面
package com.android.jni_second;
 
public class JNI {
 
 public native  void setTitle(String str);
 
 public native  int getSum(int num1, int num2);
 
 public String getTitle(){
  return mTitle;
 }
 
 private String mTitle;
}

例子很简单,看后记得吐槽哈~谢谢!

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多