JNI 编程
来源:互联网 发布:剑三成男捏脸数据花哥 编辑:程序博客网 时间:2024/06/06 02:16
我们先引入一段程序:
Java 类,随便打印一些信息吧
package com.dk.test;public class PrintInfo { public PrintInfo() { //ToDo } public print(int num, String name, byte[] b) { Log.i("dk", "num : " + num); Log.i("dk", "name : " + name); Log.i("dk", "size : " + b.length); } private native boolean parseInfo(string infofile); static { System.loadLibrary("test"); }}
JNI: 演示如何在jni中正确调用java对象的方法:
JNIEXPORT jboolean JNICALL Java_com_dk_test_parseInfo(JNIENV *env, jobject obj, jstring file) { //一定要去的全局引用,否则会被GC回收,需要记住的是JNI中传入 //的参数及返回的值都是本地引用,也就是离开了当前方法或跨线程 //时这些本地引用会失效 jobject objRef = (jobject)env->NewGlobalRef(obj); if (objRef == NULL) { LOGE("error: null pointer exception"); return false; } //通过全局引用取得对象的类 jclass objClass = env->GetObjectClass(objRef); //获取对象的方法 //objclass: 定义了该方法的类 //"print" : 需要在c/c++中调用的方法名 //"(ILjava/lang/String;[B)Z": 方法标签,用来描述方法,不 // 用死记对应关系,只需要找到类对应的class文件执行: // javap -s 类名 // 即可生成所有该类中方法的描述 // androidstudio class 在 // app/build/intermediates/classes/debug/com/..下面 jmethodId printFuncId = env->GetMethodId(objClass, "print", "(ILjava/lang/String;[B)Z"); jint num = 30; //但凡jobject的子类jstring,jclass,jarray使用时一定要使 //用全局应用,否则会报控制异常 jstring name = (jstring)env->NewGlobalRef(env->NewStringUTF("dkos")); //jarray 引用 jbyteArray b = (jbyteArray)env->NewGlobalRef(env->NewByteArray(10)); unsigned char *mail = "dk_mcu@126.com"; jbyte* bcontent = (jbyte*)(mail) //byte数组的赋值方法 env->SetByteArrayRegion(b, 0, strlen(mail), bcontent); //调用java类的方法 env->CallBooleanMethod(objRef, printFuncId, num, name, b); //回收全局引用 env->DeleteGlobalRef(name) env->DeleteGlobalRef(b); env->DeleteGlobalRef(objRef); //jni方法返回 return true;}
需要注意:假设上面调用java方法,或引用jobject对象,或是传递参数给java方法时,jobject对象若不全局引用常见的错误为:
E/dalvikvm( 5302): JNI ERROR (app bug): accessed stale local reference 0x40839e59
总结:
>
1 jni接口中使用java传递的参数或是传递参数,返回参数给java时一定使用全局引用,否则会被GC回收导致程序crash,报空指针异常等错误
2.使用引用时,env->NewGlobalRef(ref) 和env->DeleteGlobalRef(ref)成对使用,防止过多占用内存,因为全局引用GC时不会回收的
3.上面所讲都是针对android ics之后的版本,至于以前的不需要这么做
0 0
- JNI编程
- JNI编程
- JNI编程
- Jni编程
- JNI编程
- JNI编程
- JNI编程
- JNI编程
- JNI编程
- JNI编程
- JNI编程
- JNI编程
- JNI编程
- JNI 编程
- JNI编程
- JNI编程
- JNI编程经验(JNI Tips)
- JNI编程经验(JNI Tips)
- Android SDK Manager 更新代理配置
- 记Android关于.9切图的一点小技巧
- C++ 随机函数学习
- LeetCode 322. Coin Change(兑换硬币)
- 为什么线程会放弃Suspend和Resume方法
- JNI 编程
- poj1002
- Android中的Service与进程间通信(IPC)详解
- <<c>>树的遍历
- 1-PHP简介
- 1-MySQL数据库简介
- 旅游规划
- LeetCode 323. Number of Connected Components in an Undirected Graph(连通分量)
- 哈利波特的变形课考试