首页 > 系统 > Android > 正文

Android JNI基础

2019-11-09 17:36:00
字体:
来源:转载
供稿:网友

0.头文件的生成及基础参数详解

package com.example.jnitest;public class JNITest { public native String getStringFromC(); public native static String getString2FromC();}

里面有两个native方法 用命令行进入该项目src目录,使用javah命令javah com.example.jnitest.JNITest 生成头文件 com_example_jnitest_JNITest.h

/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class com_example_jnitest_JNITest */#ifndef _Included_com_example_jnitest_JNITest#define _Included_com_example_jnitest_JNITest#ifdef __cplusplusextern "C" {#endif/* * Class: com_example_jnitest_JNITest * Method: getStringFromC * Signature: ()Ljava/lang/String; */JNIEXPORT jstring JNICALL Java_com_example_jnitest_JNITest_getStringFromC (JNIEnv *, jobject);/* * Class: com_example_jnitest_JNITest * Method: getString2FromC * Signature: ()Ljava/lang/String; */JNIEXPORT jstring JNICALL Java_com_example_jnitest_JNITest_getString2FromC (JNIEnv *, jclass);#ifdef __cplusplus}#endif#endif

JniTest.c

JNIEXPORT jstring JNICALL Java_com_example_jnitest_JNITest_getStringFromC (JNIEnv *env, jobject jobj){ //JNIEnv 结构体指针 //env二级指针 //代表Java运行环境,调用Java中的代码 //简单的实现 //将C的字符串转为一个java字符串 return (*env)->NewStringUTF(env,"C String");}JNIEXPORT jstring JNICALL Java_com_example_jnitest_JNITest_getString2FromC (JNIEnv *env, jclass jcls){ return (*env)->NewStringUTF(env,"C String");}//每个native函数,都至少有两个参数(JNIEnv*,jclass或者jobject)//1)当native方法为静态方法时://jclass 代表native方法所属类的class对象(JNITest.class)//2)当native方法为非静态方法时://jobject 代表native方法所属的对象

1.类型转换

基本数据

boolean jbooleanbyte jbyte;char jchar;short jshort;int jint;long jlong;float jfloat;double jdouble;void void

引用类型(对象)

String jstringobject jobject//数组,基本数据类型的数组byte[] jByteArray//对象数组object[](String[]) jobjectArray

2.访问属性

1)访问非静态属性

package com.example.jnitest;public class JNITest { public String xm = "xmhaha"; //访问属性,返回修改后的属性 public native String accessField();}JNIEXPORT jstring JNICALL Java_com_example_jnitest_JNITest_accessField (JNIEnv *env, jobject jobj){ //jobj是对象,JNITest.class jclass cls = (*env)->GetObjectClass(env, jobj);

这里写图片描述

//jfieldID //属性名称,属性签名 jfieldID fid = (*env)->GetFieldID(env, cls, "xm", "Ljava/lang/String;"); //xm >> super xm //获取xm属性的值 //Get<Type>Field jstring jstr = (*env)->GetObjectField(env, jobj, fid); //jstring -> c字符串 //isCopy 是否复制(true代表赋值,false不复制) char *c_str = (*env)->GetStringUTFChars(env,jstr,JNI_FALSE); //拼接得到新的字符串 char text[20] = "super "; strcat(text,c_str); //c字符串 ->jstring jstring new_jstr = (*env)->NewStringUTF(env, text); //修改xm //Set<Type>Field (*env)->SetObjectField(env, jobj, fid, new_jstr); return new_jstr;}

2)访问静态属性

package com.example.jnitest;public class JNITest { public static int count = 8; //访问属性,返回修改后的属性 public native String accessStaticField();}JNIEXPORT jstring JNICALL Java_com_example_jnitest_JNITest_accessStaticField (JNIEnv *env, jobject jobj){ //jclass jclass cls = (*env)->GetObjectClass(env, jobj); //jfieldID jfieldID fid = (*env)->GetStaticFieldID(env, cls, "count", "I"); //GetStatic<Type>Field jint count = (*env)->GetStaticIntField(env, cls, fid); count++; //修改 //SetStatic<Type>Field (*env)->SetStaticIntField(env,cls,fid,count);}

3.访问方法

1)访问非静态方法

package com.example.jnitest;public class JNITest { public native void accessMethod(); /** * 产生指定范围的随机数 * * @param max * @return */ public int genRandomInt(int max) { return new Random().nextInt(max); }}

获得方法的签名: 用命令行进入项目的bin/classes目录,使用javap -s -p 这里写图片描述 得到方法签名 这里写图片描述

JNIEXPORT void JNICALL Java_com_example_jnitest_JNITest_accessMethod (JNIEnv *env, jobject jobj){ //jclass jclass cls = (*env)->GetObjectClass(env, jobj); //jmethodID jmethodID mid = (*env)->GetMethodID(env, cls, "genRandomInt", "(I)I"); //调用 //Call<Type>Method jint random = (*env)->CallIntMethod(env, jobj, mid, 200); PRintf("random num:%ld",random); //.....}

2)访问静态方法

package com.example.jnitest;public class JNITest { public native void accessStaticMethod(); public static String getUUID() { return UUID.randomUUID().toString(); }}JNIEXPORT void JNICALL Java_com_example_jnitest_JNITest_accessStaticMethod (JNIEnv *env, jobject jobj){ //jclass jclass cls = (*env)->GetObjectClass(env, jobj); //jmethodID jmethodID mid = (*env)->GetStaticMethodID(env, cls, "getUUID", "()Ljava/lang/String;"); //调用 //CallStatic<Type>Method jstring uuid = (*env)->CallStaticObjectMethod(env, cls, mid); //..... }

3)访问构造方法

//使用java.util.Date产生一个当前时间JNIEXPORT jobject JNICALL Java_com_dongnaoedu_jni_JniTest_accessConstructor(JNIEnv *env, jobject jobj){ jclass cls = (*env)->FindClass(env, "java/util/Date"); //jmethodID(构造方法用<init>) jmethodID constructor_mid = (*env)->GetMethodID(env, cls, "<init>", "()V"); //实例化一个Date jobject date_obj = (*env)->NewObject(env, cls, constructor_mid); //调用getTime方法 jmethodID mid = (*env)->GetMethodID(env, cls, "getTime", "()J"); jlong time = (*env)->CallLongMethod(env, date_obj, mid); return date_obj;}
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表