1、访问构造方法
jclass cls = (*env)->FindClass(env,"java/util/Date");jmethodID constructor_mid = env->GetMethodID(env,cls,"","()V");jobject date_obj = env->NewObject(env,cls,constructor_mid); (*env)->DeleteLocalRef(env,data_obj);
2、访问父类的构造方法
char* c_str = "迪丽热巴";jclass str_cls = (*env)->FindClass(env,"Ljava/langString;");jmethodID constructor_mid = (*env)->GetMethodID(env,str_cls,"","([BLjava/lang/String;])V") jbyteArray bytes = (*env)->NewByteArray(env,strlen(c_str)); (*env)->SetByteArrayRegion(env,bytes,0,strlen(c_str),c_str); jstring charsetName = (*env)->NewStringUTF(env,"GB2312");return (*env)->NewObject(env,str_cls,constructor_mid,bytes,charsetName);
3、数组处理_JNI引用 数组排序 int[] arr
1、函数指针:
#includeint compare(const void* a,const void* b){return (*a) -(*b);} jint * elems = (*eng)->GetIntArrayElements(env,arr,NULL); int len = (*eng)->GetArrayLength(env,arr); qsort(elems,len,sizeof(jint),compare); (*env)->ReleaseIntArrayElements(env,arr,elems,0);
2、返回一个int类型的数组
jintArray jint_arr = (*env)->NewInntArray(env,len)jint* elems = (*env)->GetIntArrayElements(env,jint_arr,NULL);for(int i=0;iReleaseIntArrayElements(env,jint_arr,elems,0);return jint_arr;
3、局部引用和全局引用
1、局部引用,通过DeleteLocalRef手动释放对象
#1、访问一个很大的java对象,使用完之后,还要进行复杂的耗时操作
#2、创建了大量的局部引用,占用了太多的内存,而且这些局部引用跟后面的操作没有关联。2、全局引用,多个方法里面都可以引用
<!-- 解决数据共享问题(可以跨多个线程),手动控制内存的使用 -->
<!-- 自己处理线程安全问题 -->jstring global_str;void createGlobalRef(){ jstring obj = (*env)->NewStringUTF(env,"jni is powerful"); global_str = (*env)->NewGlobalRef(obj);}void getGlobalRef(){ return global_str;}void deleteGlobalRef(){ (*env)->DeleteGlobalRef(global_str);}
class JniTest{ public native void createGlobalRef(); public native void getGlobalRef(); public native void deleteGlobalRef(); public static void main(String[] args){ JniTest t = new JniTest(); t.createGlobalRef(); t.getGlobalRef(); t.deleteGlobalRef(); t.getGlobalRef(); }}
3、弱全局引用
<!-- 节省内存,在内存不足时可以是释放所引用的对象 -->
<!-- 可以引用一个不常用的对象,如果为NULL,临时创建 --><!-- 创建: NewWeakGlobalRef,销毁 DeleteGlboalWeakRef -->4、异常处理 (Native 异常,无法在Java层catch) 只能在native 层处理
void exception(JNIEnv* env,jobject obj){ jclass cls = (*env)->GetObjectClass(env,obj); jfieldId fid = (*env)->GetFieldID(env,cls,"key2","Ljava/lang/String;"); jthrowable exception = (*env)->ExceptionOccurred(env); if(exception != null){ (*env)->ExceptionClear(env); fid = (*env)->GetFieldID(env,cls,"key","Ljava/lang/String;"); } jstring jstr = (*env)->GetObjectField(env,jobj,fid); char * str = (*env)->GetStringUTFChars(env,jstr,NULL); if(stricmp(str,"super jason1") != 0){ jclass newExeCls = (*env)->FindClass(env,"Ljava/lang/IllegalArgumentException;"); (*env)->ThrowNew(env,newExeCls,"Key's value is invalid!"); }}
java 代码
t.exception();
4、缓存策略
1、使用局部静态变量
void cached(JNIEnv* env,jobject obj){ jclass cls = (*env)->GetObjectClass(env,obj); static jfieldID = key_id = null; if(key_id == null){ key_id = (*env)->GetFieldID(env,cls,"key","Ljava/lang/String;"); print("==========GetFieldID=========="); }}
2、initIDs(),
<!-- 在C层后面使用的对象在一个方法里面初始化,initIDs()在加载库的时候调用。 -->
javapublic static void initIDs();static { System.load("lib"); initIDs();}
C :
jfieldID key_fid;initIds(JNIEnv* env,jclass jcls){ key_fid = (*env)->GetFieldID(env,jcls,"key","Ljava/lang/String;");}
posted on 2019-06-13 20:26 阅读( ...) 评论( ...)