Android JNI基础
Posted 薛萌
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android JNI基础相关的知识,希望对你有一定的参考价值。
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 __cplusplus
extern "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 jboolean
byte jbyte;
char jchar;
short jshort;
int jint;
long jlong;
float jfloat;
double jdouble;
void void
引用类型(对象)
String jstring
object 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;
以上是关于Android JNI基础的主要内容,如果未能解决你的问题,请参考以下文章