JNI c++对象与java对象互关联
来源:互联网 发布:阿拉丁自有数据电解铝 编辑:程序博客网 时间:2024/06/16 22:06
android中如果需要调用c++代码需要写jni将java操作转接到c++代码中.但是大部分的文章都只是通过讲解通过 extern "C" 代码来访问具体功能.
在这里我要讲一种方便的方法将java对象和c++对象互相绑定起来.
第一步:
JNIObject.java:
public class JNIObject { protected long mObj;}MediaController.java
public class MediaController extends JNIObject { public MediaController() { construct(); } @Override protected void finalize() throws Throwable { destruct(); super.finalize(); } @Keep private void logMessage(String msg){ Log.d("AAA", "msg:"+msg); } static { System.loadLibrary("media_controller-lib"); } private native void construct(); private native void destruct(); public native int ntopen(String file); public native void ntclose(); public native int ntplay(); public native void ntpause(); public native void ntseek(int sec); public native String nttest(int msg);}
jni代码:
static JavaVM* g_VM = NULL;class JNIMediaControl :public MediaControl{public: JNIMediaControl() :javaVM(NULL),env_(NULL),thiz(NULL) { } void attachParent(JavaVM * vm,JNIEnv *env,jobject object) { javaVM =vm; thiz = env->NewGlobalRef(object); } void detachParent(JNIEnv *env) { env->DeleteGlobalRef(thiz); thiz = NULL; }private: void AttachThread() { if(javaVM == NULL) return; if(thiz == NULL) return ; int ret = javaVM->AttachCurrentThread(&env_,NULL); if(ret != 0) { } } void DetachThread() { if(javaVM == NULL) return; javaVM->DetachCurrentThread(); env_ = NULL; } virtual void Run() { AttachThread(); MediaControl::Run(); DetachThread(); } void SendPacket(int64_t timestamp,AVFrame *frame) { JNIEnv *env = env_; if(env == NULL) return; char buffer[64]; sprintf(buffer,"%lld",timestamp); jstring msg_ = env->NewStringUTF(buffer); jclass clazz = env->GetObjectClass(thiz); jmethodID jid = env->GetMethodID(clazz,"logMessage","(Ljava/lang/String;)V"); env->CallVoidMethod(thiz,jid,msg_); env->DeleteLocalRef(msg_); }private: JavaVM* javaVM; JNIEnv *env_; jobject thiz;};
#define CONSTRUCT(T) { T *t = new T(); \ jclass clazz = (jclass)(*env).GetObjectClass(thiz); \ jfieldID fid = (jfieldID)(*env).GetFieldID(clazz, "mObj", "J"); \ jlong jstr = (jlong) (*env).GetLongField(thiz, fid); \ (*env).SetLongField(thiz, fid, (jlong)t);}#define OBJECT(T,name) jclass clazz = (jclass)env->GetObjectClass(thiz); \ jfieldID fid = env->GetFieldID(clazz, "mObj","J"); \ T *name = (T *)env->GetLongField(thiz, fid);#define DESTRUCT(T) {jclass clazz = (jclass)env->GetObjectClass(thiz); \ jfieldID fid = env->GetFieldID(clazz, "mObj","J"); \ T *object = (T *)env->GetLongField(thiz, fid); \ if(object != NULL) delete object; \ (*env).SetLongField(thiz, fid, (jlong)0);}extern "C"JNIEXPORT void JNICALLJava_com_example_jfyang_mediacontrollerdemo_MediaController_construct(JNIEnv* env, jobject thiz){ CONSTRUCT(JNIMediaControl); OBJECT(JNIMediaControl,control); if(control == NULL) return ; control->attachParent(g_VM,env,thiz);}extern "C"JNIEXPORT void JNICALLJava_com_example_jfyang_mediacontrollerdemo_MediaController_destruct(JNIEnv *env, jobject thiz) { { OBJECT(JNIMediaControl, control); if (control == NULL) return; control->detachParent(env); } DESTRUCT(JNIMediaControl);}extern "C"JNIEXPORT void JNICALLJava_com_example_jfyang_mediacontrollerdemo_MediaController_ntclose(JNIEnv *env, jobject thiz) { OBJECT(JNIMediaControl,control); if(control == NULL) return ; control->Close();}JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved){ JNIEnv* env = NULL; jint result = -1; if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) { return -1; } assert(env != NULL); g_VM = vm; return JNI_VERSION_1_4;}
在android中需要被底层使用的对象均继承自JNIObject.
JNI代码中 通过
CONSTRUCT构造一个自定义对象与JNIObject关联起来.OBJECT获取与JNIObject关联起来的对象DESTRUCT释放与JNIObject关联起来的对象具体的功能还是通过jni的c方法调用并转至c++对象中.
在jni底层线程中有时需要回调数据至android上层中,这种情况我们可以通过回调上层方法完成.
1.先将上层父对象建立全局引用
thiz = env->NewGlobalRef(object);
注意:所有的在底层线程中操作的上层对象均需要建立GlobalRef才能使用,否则会崩溃.
2.通过JNI_Onload获取本模块加载时传入的虚拟机并全局保存
3.通过虚拟机 在线程中创建一个线程相关JNIEnv.
4.通过线程相关JNIEnv 调用 GlobalRef对象的方法.
阅读全文
0 0
- JNI c++对象与java对象互关联
- Android JNI对象与Java对象的绑定
- JNI创建Java对象
- JNI引用Java对象
- JNI操作Java对象
- Objective-C的Category与关联对象实现原理
- JNI java和c之间对象的传递
- 用jni的方式c/c++语言创建Java对象
- java 层调用Jni(Ndk) 持久化c c++ 对象
- JNI学习(一)(c和java层对象互相调用)
- Android中JNI高级应用 - 本地C代码中创建Java对象及本地JNI对象的保存
- Android中JNI高级应用 - 本地C代码中创建Java对象及本地JNI对象的保存 .
- Android中JNI高级应用 - 本地C代码中创建Java对象及本地JNI对象的保存
- 关联对象
- 关联对象
- json对象与java对象互转
- obj-c编程19:关联对象
- Java 对象引用与对象
- 8086汇编-图示HANOI的移动过程
- Mysql,Oracle,Pgsql 比较
- 搭建网站,和把大象装冰箱一样简单?
- ehcache初使用
- iOS AVAssetWriter 实现高分辨率录制视频,生成低体积的视频文件
- JNI c++对象与java对象互关联
- UEditor 图片上传
- WPF DataGrid 使用
- ActiveMQ的Hello World实例
- shiro springmvc
- mycat 启动和关闭服务不起作用解决方案
- ORA-32004 的错误处理
- centos 无法启动mysql问题
- hasOwnProperty() 、in 操作符与 for-in 循环