【NDK】【019】AttachCurrentThread,DetachCurrentThread的正确使用姿势

JNI线程绑定的普通用法


	JNIEnv *env = nullptr;
	jvm->AttachCurrentThread(&env, nullptr);
	env->CallVoidMethod(obj, one rrorMethod, -1);
	jvm->DetachCurrentThread();

普通用法的缺陷

如果子线程是在C++中创建的,然后通过以上代码来执行Java回调,则没有任何问题

但如果子线程是在Java代码中创建的,Java调用了C++代码,C++代码再调用Java回调方法,就会有问题

因为C++在调用DetachCurrentThread时,这个方法本身就是运行在Java代码之内的,Java仍然在使用此线程,所以是不可能完成解绑操作的

更完善的做法时,在AttachCurrentThread和DetachCurrentThread前,先判断当前代码块,是否已经和Java线程的运行环境绑定,如果已绑定,则没必要再次AttachCurrentThread或DetachCurrentThread

如果我们不这样做,代码运行时则可能会抛出以下的错误

attempting to detach while still running code

正确的使用姿势


	JNIEnv *env = nullptr;
	bool detached = jvm->GetEnv((void **) &env, JNI_VERSION_1_6) == JNI_EDETACHED;
	if (detached) jvm->AttachCurrentThread(&env, nullptr);
	env->CallVoidMethod(obj, one rrorMethod, -1);
	if (detached) jvm->DetachCurrentThread();

上一篇:一线互联网移动架构师NDK模块开发!重难点整理


下一篇:Ndk开发入门教程