Android JNI基础

来源:互联网 发布:食堂刷卡机数据采集 编辑:程序博客网 时间:2024/06/08 01:01

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;}
1 0
原创粉丝点击