记录下:
默认 是attatch的 (从java线程传入 env JNI方式 !invoke)
Webrtc 获取JNIEnv
void VideoSinkWrapper::OnFrame(const VideoFrame& frame) {
JNIEnv* jni = AttachCurrentThreadIfNeeded();
ScopedJavaLocalRef<jobject> j_frame = NativeToJavaVideoFrame(jni, frame);
Java_VideoSink_onFrame(jni, j_sink_, j_frame);
ReleaseJavaVideoFrame(jni, j_frame);
}
// Return a |JNIEnv*| usable on this thread. Attaches to |g_jvm| if necessary.
JNIEnv* AttachCurrentThreadIfNeeded() {
JNIEnv* jni = GetEnv();
if (jni)
return jni;
RTC_CHECK(!pthread_getspecific(g_jni_ptr))
<< "TLS has a JNIEnv* but not attached?";
std::string name(GetThreadName() + " - " + GetThreadId());
JavaVMAttachArgs args;
args.version = JNI_VERSION_1_6;
args.name = &name[0];
args.group = nullptr;
// Deal with difference in signatures between Oracle's jni.h and Android's.
#ifdef _JAVASOFT_JNI_H_ // Oracle's jni.h violates the JNI spec!
void* env = nullptr;
#else
JNIEnv* env = nullptr;
#endif
RTC_CHECK(!g_jvm->AttachCurrentThread(&env, &args))
<< "Failed to attach thread";
RTC_CHECK(env) << "AttachCurrentThread handed back NULL!";
jni = reinterpret_cast<JNIEnv*>(env);
RTC_CHECK(!pthread_setspecific(g_jni_ptr, jni)) << "pthread_setspecific";
return jni;
}
//java
new Thread(new Runnable() {
@Override
public void run() {
String test = testJNIThread();
Log.e(TAG, "test:" + test);
}
}).start();
//c++
JNIEXPORT jstring JNICALL
Java_com_tyeralin_jnithread_MainActivity_testJNIThread(JNIEnv *env, jobject thiz) {
JavaVM *vm = NULL;
int result = env->GetJavaVM(&vm);
if (!result) {
bool detatched = (vm->GetEnv((void **) &env, JNI_VERSION_1_6) == JNI_EDETACHED);
if (detatched) {
vm->AttachCurrentThread(&env, nullptr);
}
LOGD("detatched:%d", detatched);
jclass cz = env->FindClass("com/tyeralin/jnithread/MainActivity");
if (cz == NULL)
goto FAILED;
jmethodID print = env->GetMethodID(cz, "print", "(Ljava/lang/String;)V");
if (print == NULL)
goto FAILED;
const char *value = "from jni";
jstring args = env->NewStringUTF(value);
env->CallVoidMethod(thiz, print, args);
if (detatched) {
vm->DetachCurrentThread();
}
return args;
}
FAILED:
return NULL;
}