Fork me on GitHub

C/C++&java communicate with each other 之 video file-streaming

 
使用开源通信框架alljoyn来做设备,服务的搜索、发现,通信,详细原理参考
 
gstreamer作媒体播放。
 
有兴趣同学可以看下https://github.com/europelee/AjUtil,简单的多媒体文件流分享(上图即它的architecture)
 
                                                            (alljoyn设备、服务通告,发现示意图)
涉及面:
 
1. JNI中的多native线程与java通信处理:
JNIEnv, java_vm, thread: JNIEnv不能为多个native线程共同拥有, 即JNIEnv对于每个线程是唯一的,它是线程相关的,那么
对于一个native线程如果需要使用JNIEnv, 需要通过javavm的AttachCurrentThread方法来获取它自有的。
 
比如下面的 set_ui_message,当内部native线程运行时需要通知某些消息到android 的java层 , 通过get_jni_env来获取它自有JNIEnv.
 
2.Thread-Specific Data
大家注意到current_jni_env? 如果 set_ui_message在多个native线程里面被调用,那get_jni_env函数里面pthread_getspecific搞什么鬼,
current_jni_env就一个全局变量,能保证每个线程的env指针唯一
 
常情况下,一个全局变量是为进程内的多个线程共享,但如果线程想单独拥有它,那么可以使用POSIX提供的Thread-Specific Data, 即
线程私有数据,这样看起来这是一个全局变量,所有线程都可以使用它,但它的值在每一个线程中又是单独存储的,一个使用同名而不同变量地址的线程相关数据结构,通过pthread_key_create函数来创建 
pthread_key_create(&current_jni_env, detach_current_thread);
 

3. code:

/* Register this thread with the VM */
static JNIEnv *attach_current_thread(void) {
 JNIEnv *env;
 JavaVMAttachArgs args;
 
 GST_DEBUG("Attaching thread %p", g_thread_self());
 args.version = JNI_VERSION_1_4;
 args.name = NULL;
 args.group = NULL;
 
 if ((*java_vm)->AttachCurrentThread(java_vm, &env, &args) < 0) {
  GST_ERROR("Failed to attach current thread");
  return NULL;
 }
 
 return env;
}
 
/* Retrieve the JNI environment for this thread */
static JNIEnv *get_jni_env(void) {
 JNIEnv *env;
 
 if ((env = pthread_getspecific(current_jni_env)) == NULL) {
  env = attach_current_thread();
  pthread_setspecific(current_jni_env, env);
 }
 
 return env;
}
 
/* Change the content of the UI's TextView */
static void set_ui_message(const gchar *message, CustomData *data) {
 JNIEnv *env = get_jni_env();
 GST_DEBUG("Setting message to: %s", message);
 jstring jmessage = (*env)->NewStringUTF(env, message);
 (*env)->CallVoidMethod(env, data->app, set_message_method_id, jmessage);
 if ((*env)->ExceptionCheck(env)) {
  GST_ERROR("Failed to call Java method");
  (*env)->ExceptionClear(env);
 }
 (*env)->DeleteLocalRef(env, jmessage);
}
posted @ 2015-06-19 17:36  europelee  阅读(298)  评论(0编辑  收藏  举报