示例:

int size = (*env)->GetArrayLength(env, array); //获得数组array的长度 ,返回整型


jarray array = ((*env)->GetObjectArrayElement(env, array, i)); //获得对象数组array的元素i,

jint *pp = (*env)->GetIntArrayElements(env, (jintArray)array, 0 ); //获得整型数组array的元素0,返回指针jint*类型

(*env)->ReleaseIntArrayElements(env, (jintArray)array, pp,0 ); //释放整型数组array的元素pp,

(*env)->DeleteLocalRef(env,intArr); //释放内存 调用GetObjectArrayElement不需要释放,但用完需要调用DeleteLocalRef删除对应局部引用,如果作为返回值就不用删除。


在如下情况下,会用到类型之间的转换:


1java方法里面将参数传入本地方法;

2在本地方法里面创建java对象;

3在本地方法里面return结果给java程序。


JAVA类型与本地类型的对应关系:

Java类型 本地类型 字节(bit)

boolean jboolean 8, unsigned
byte jbyte 8
char jchar 16, unsigned
short jshort 16
int jint 32
long jlong 64
float jfloat 32
double jdouble 64
void void n/a
java对象 jobject

注意:在使用完你所转换之后的对象之后,必须调用ReleaseStringUTFChars方法,让JVM释放转换成UTF-8的string的对象的空间,

否则,JVM中会一直保存该对象,不会被垃圾回收器回收,导致内存溢出。


访问String的一些方法:

GetStringUTFChars //将jstring转换成为UTF-8格式的char*


GetStringChars //将jstring转换成为Unicode格式的char*


ReleaseStringUTFChars //释放指向UTF-8格式的char*的指针


ReleaseStringChars // 释放指向Unicode格式的char*的指针


NewStringUTF //创建一个UTF-8格式的String对象


NewString //创建一个Unicode格式的String对象


GetStringUTFLengt //获取UTF-8格式的char*的长度


GetStringLength // 获取Unicode格式的char*的长度


访问Array对象:

示例:

jintArray arr;

jsize len = (*env)->GetArrayLength(env, arr); //1 获取数组的长度:

jint *body = (*env)->GetIntArrayElements(env, arr, 0); // 2 获取指向arr数组元素0的指针

for (i=0; i<len; i++) { sum += body[i];} // 3 使用指针取出Array中的元素

(*env)->ReleaseIntArrayElements(env, arr, body, 0); //4释放数组元素的引用 提醒JVM回收arr数组元素的引用。


获取数组元素指针:

函数 数组类型

GetBooleanArrayElements boolean
GetByteArrayElements byte
GetCharArrayElements char
GetShortArrayElements short
GetIntArrayElements int
GetLongArrayElements long
GetFloatArrayElements float
GetDoubleArrayElements double


释放数组元素指针:

函数 数组类型

ReleaseBooleanArrayElements boolean
ReleaseByteArrayElements byte
ReleaseCharArrayElements char
ReleaseShortArrayElements short
ReleaseIntArrayElements int
ReleaseLongArrayElements long
ReleaseFloatArrayElements float
ReleaseDoubleArrayElements double

访问自定义Java对象数组

GetObjectArrayElement
SetObjectArrayElement


访问Java对象

示例:

jclass cls = (*env)->GetObjectClass(env, obj); // 1 获取你需要访问的Java对象的类: obj对应的jclass。

jmethodID mid = (*env)->GetMethodID(env, cls, "callback", "(I)V"); // 2 获取你要使用的方法的MethdoID。

其参数的意义:
  env-----JNIEnv
  cls-----第一步获取的jclass
  "callback"-----要调用的方法名
  "(I)V"-----方法的Signature签名(见后面)

(*env)->CallVoidMethod(env, obj, mid, depth); //3 使用CallVoidMethod方法调用方法。

参数的意义:
  env-----JNIEnv
  obj----通过本地方法穿过来的jobject
  mid----要调用的MethodID(即第二步获得的MethodID)
  depth----方法需要的参数(对应方法的需求,添加相应的参数)

方法的Signature签名
方法的Signature是由方法的参数和返回值的类型共同构成的,结构为:
"(argument-types)return-type"

其中Java程序中参数类型和其对应的值如下:

Signature签名 Java中的类型

Z boolean
B byte
C char
S short
I int
J long
F float
D double
L fully-qualified-class //L类名
[ type //数组
V void

一个Java类的方法的Signature签名可以通过javap命令获取:

javap -s -p Java类名



给调用的函数传参数:

通常我们直接在methodID后面将要传的参数添加在后面,但是还有其他的方法也可以传参数:

CallVoidMethodV //获取一个数量可变的列表作为参数;
CallVoidMethodA //获取一个union。

调用静态方法:
就是将第二步和第三步调用的方法改为对应的:

jmethodID GetStaticMethodID //获取对应的静态方法的ID
CallStaticIntMethod // 调用静态方法

调用超类的方法:

CallNonvirtual<TYPE>Method
env->CallNonvirtualVoidMethod(p,clazz_Father,id_Father_function); //调用父类方法

访问Java对象的属性:

访问Java对象的属性和访问Java对象的方法基本上一样,只需要将函数里面的Method改为Field即可.

示例:

jclass objectClass = (env)->FindClass("com/sundy/jnidemo/DiskInfo"); //获得JAVA中的实例类
jfieldID fieldID = env->GetFieldID(native_clazz,"name","Ljava/lang/String;"); //获得域的ID
jint number= env->GetIntField(obj,fieldID); //获得域属性
env->SetIntField(obj,fieldID,18880L) ; //设置


不相关的额外函数:
char* jstringToWindows( JNIEnv *env, jstring jstr ); //将jstring类型转换成windows类型
jstring WindowsTojstring( JNIEnv* env, char* str ); //将windows类型转换成jstring类型
//将jstring类型转换成windows类型
char* jstringToWindows( JNIEnv *env, jstring jstr )
{
int length = (env)->GetStringLength(jstr );
const jchar* jcstr = (env)->GetStringChars(jstr, 0 );
char* rtn = (char*)malloc( length*2+1 );
int size = 0;
size = WideCharToMultiByte( CP_ACP, 0, (LPCWSTR)jcstr, length, rtn,(length*2+1), NULL, NULL );
if( size <= 0 )
return NULL;
(env)->ReleaseStringChars(jstr, jcstr );
rtn[size] = 0;
return rtn;
}
//将windows类型转换成jstring类型
jstring WindowsTojstring( JNIEnv* env, char* str )
{
jstring rtn = 0;
int slen = strlen(str);
unsigned short * buffer = 0;
if( slen == 0 )
rtn = (env)->NewStringUTF(str );
else
{
int length = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)str, slen, NULL, 0 );
buffer = (unsigned short *)malloc( length*2 + 1 );
if( MultiByteToWideChar( CP_ACP, 0, (LPCSTR)str, slen, (LPWSTR)buffer, length ) >0 )
rtn = (env)->NewString( (jchar*)buffer, length );
}
if( buffer )
free( buffer );
return rtn;
}

更多相关文章

  1. Android(安卓)学习笔记 databinding简单使用:使用databinding在li
  2. android学习日记之fragment
  3. android 反射应用
  4. Android(安卓)9.0 Bluetooth源码分析(三)蓝牙配对流程
  5. android sdk 下载失败解决方法
  6. android Button字体设置颜色
  7. Android(安卓)IllegalArgumentException: Cannot draw recycled
  8. Android(安卓)签名打包出现的错误的解决方法以及代码中获取应用
  9. Android(安卓)SDK 离线安装方法

随机推荐

  1. Android异步加载源码示例
  2. android在一个app程序中,打开另一个app的
  3. android的图片加载几种方法
  4. Android(安卓)SDK安装
  5. Android SwipeToDismiss:左滑/右滑删除Lis
  6. android xml之动画篇 alpha、scale、tran
  7. Android(安卓)/ Java ------ Sha1 and Md
  8. android 联系人 增删改查
  9. Android Volley.jar包下载(第三方开源网
  10. android launcher源码分析