《Android框架揭秘》读书笔记——JNI

形式const jbyte* GetStringUTFChars(JNIEnv* env, jstring string, jboolean* usCopy)
说明将Java字符串对象转换成UTF-8字符串(C字符串),并返回指针
参数isCopy:当String对象中的祖父穿被转换成UTF-8字符串,被复制到内存,且指针被返回时,*isCopy设置为JNI_TRUE,否则设置为JNI_FALSE。
const char *str = (*env)->GetStringUTFChars(string, 0);
形式jfieldGetStaticFieldID(JNIEnv* env, jclass clazz, const char* name, const char* signature)
说明返回对象中指定的静态成员变量的jfieldID的值
参数clazz:包含成员变量的类的jclass
参数name:成员变量名
参数signature:成员变量签名
形式jfieldGetFieldID(JNIEnv* env, jclass clazz, const char* name, const char* signature)
说明返回对象中指定的成员变量的jfieldID的值
参数clazz:包含成员变量的类的jclass
参数name:成员变量名
参数signature:成员变量签名
形式<jnitype> GetStatic<type>Field(JNIEnv *env, jclass clazz, jfieldID fieldID)
说明返回clazz类中ID为field的静态变量的值
<type>指Object、Boolean、Byte、Char、Short、Int、Long、Float、Double九种基本类型。
<jnitype>指jobject、jboolean、jbyte、jchar、jshort、jint、jlong、jfloat、jdouble九种基本类型。
形式<jnitype> Get<type>Field(JNIEnv *env, jobject obj, jfieldID fieldID)
说明返回clazz类中ID为field的变量的值
fid = env->GetStaticFieldID(clzz, "staticIntField", "I");
staticIntField = env->getStaticIntField(clazz, fid);
形式jclass FindClass(JNIEnv env, const char name)
说明查找name指定的Java类
形式jmethodID GetMethodID(JNIEnv* env, jclass clazz, const char* name, const char* signature)
说明获取clazz类对象的指定方法的ID。注意,方法名(name)与签名应当保持一致。若获取类构造方法的ID,方法名为“<init>”
若方法ID错误,则返回NULL
形式jobject NewObject(JNIEnv* env, jclass clazz, jmethodID methodID, …)
说明生成指定类的对象。methodID指类的构造方法的ID
参数…:传递给类构造方法的参数
返回值返回类对象的引用。若发生错误,返回NULL
targetClass = env->FindClass(“JniTest”);
mid = env->GetMethodID(targetClass, "<init>", "(I)V");
newObject = env->NewObject(targetClass, mid, 100);
形式jobject NewGlobalRef(JNIEnv *env, jobject obj)
说明为obj指定的类或对象,生成全局引用。当全局引用使用完毕后,应当调用名称为DeleteGlobalRef()的JNI函数,显性地将全局引用销毁。
参数obj:待生成全局引用的引用值
返回值返回生成的全局引用,若发生错误,则返回NULL
形式<jnitype> CallStatic<type>Method(JNIEnv* env, jclass clazz, jmethodID methodID, …)
说明调用methodID指定的类的静态方法
<type>出了前面的九种类型外,又添加了void类型。返回值类型<jnitype>也增加了void类型。
参数…:传递给待调用方法的参数
返回值被调方法的返回值
形式<jnitype> Call<type>Method(JNIEnv* env, jobject obj, jmethodID methodID, …)
说明调用methodID指定的Java对象的方法
参数…:传递给待调用方法的参数
返回值被调方法的返回值
targetClass = env->GetObjectClass(newObject);
mid = env->GetMethodID(targetClass, "callByNative", "(I)I");
result = env->CallIntMethod(newObject, mid, 200);
形式void SetStatic<type>Field(JNIEnv* env, jclass clazz, jfieldID fieldID, <type> value)
说明设置fieldID指定的Java类静态成员变量的值
形式void Set<type>Field(JNIEnv* env, jclass clazz, jfieldID fieldID, <type> value)
说明设置fieldID指定的Java对象的成员变量的值
fid = env->GetFieldID(targetClass, "intField", "I")
env->setIntField(newObject, fid, result);
形式jint JNI_CreateJavaVM(JavaVM **vm, JNIEnv **env, void *vm_args)
说明装在并初始化Java虚拟机
参数vm:JavaVM指针的地址
env:JNI接口指针的地址
vm_args:传递给Java虚拟机的参数
返回值成功,返回0;失败:返回负值
形式jstring NewStringUTF(JNIEnv* env, const char *bytes)
说明将UTF-8形式的C字符串转换成java.lang.String对象
返回值成功,返回String对象的jstring类型的引用;失败,返回NULL
形式jarray NewObjectArray(JNIEnv* env, jsize length, jclass elementClass, jobject initialElement)
说明生成由elementClass对象组成的数组。数组元素个数由length指定,initialElement参数用来初始化对象数组
返回值若成功,则返回数组引用;失败,则返回NULL
#include <jni.h>
int main()
{
    JNIEnv *env;
    JavaVM *vm;
    JavaVMInitArgs vm_args;
    JavaVMOption options[1];
    jint res;
    jclass cls;
    jmethodID mid;
    jstring jstr;
    jclass stringClass;
    jobjectArray args;

    // 生成Java虚拟机选项
    options[0].optionString = "-DJava.class.path=."
    vm_args.versino = 0x00010002;
    vm_args.options = options;
    vm_args.nOptions = 1;
    vm_args.ignoreUnrecognized = JNI_TRUE;

    // 生成Java虚拟机
    res = JNI_CreateJavaVM(&vm, (void**)&env, &vm_args);

    // 查找并加载类
    cls = (*env)->FindClass(env, "InvocationApiTest");

    // 获取main()方法的ID
    mid = (*env)->GetStaticMethodID(env, cls, "main", "([LJava/lang/String;)V");

    // 生成字符串对象,用作main()方法的参数
    jstr = (*env)->NewString UTF(env, "Hello Invocation API!");
    stringClass = (*env)->FindClass(env, "java/lang/String");
    args = (*env)->NewObjectArray(env, 1, stringClass, jstr);

    // 调用main()方法
    (*env)->CallStaticVoidMethod(env, cls, mid, args);

    // 销毁Java虚拟机
    (*vm)->DestroyJavaVM(vm);
}
形式jint JNI_OnLoad(JavaVM * vm, void * reserved)
说明Java虚拟机加载本地库时会调用JNI_OnLoad()函数。在使用加载库的过程中,JNI_OnLoad()函数会想Java虚拟机确认JNI的版本。若库中不包含JNI_OnLoad()函数,Java虚拟机会认为相关库要求JNI1.1版本支持。
形式jint GetEnv(JavaVM* vm, void ** env, jint version)
说明判断Java 虚拟机是否支持version指定的JNI版本,而后将JNI接口指针设置到*env中
返回值若执行成功,返回0;失败,返回负数
形式jarray RegisterNatives(JNIENv * env, jclass clazz, const JNINativeMthod * methods, jint nMethods)
说明将clazz指定类中的本地方法与JNI本地函数连接在一起,链接信息保存在JNINativeMthod结构体数组中
返回值若执行成功,返回数组引用;否则,返回NULL
#include "jni.h"
#include <stdio.h>

void printHelloNative(JNIEnv* env, jobject obj);
void printStringNative(JNIEnv* env, jobject obj, jstring string);

JNIExport jni JNICALL JNI_OnLoad(JavaVM *vm, void * reserved)
{
    JNIEnv* env = NULL;
    JNINativeMethod nm[2];
    jclass cls;
    jint result = -1;

    if(vm->GetEnv((void **)&env, JNI_VERSION_1_4) != JNI_OK) {
        printf("ERROR");
        return JNI_ERR;
    }

    cls = env->FindClass("HelloJNI");

    nm[0].name = "printHello";
    nm[0].signature = "()V";
    nm[0].fnPtr = (void *)printHelloNative;

    nm[1].name = "printString";
    nm[1].signature = "(Ljava/lang/String;)V";
    nm[1].fnPtr = (void *)printStringNative;

    env->RegisterNatives(cls, nm, 2);

    return JNI_VERSION_1_4;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值