在Android中,如果我从不同的Java线程调用来自同一JNI库的函数,是否会在同一本机线程或不同的本机线程中调用JNI函数?
所有Android版本的答案是否相同?
(我怀疑如果你调用一个需要初始化并在同一本机线程上调用的JNI库,AsyncTask
不是最好的选择。)
答案 0 :(得分:0)
关于本机代码,Java线程和本机代码之间没有区别,它只是一个线程。您不会通过从Java调用本机方法来更改线程,它将在与之前的Java代码相同的线程上执行。
Java VM为每个线程保存一些额外信息,因此必须首先将以本机代码创建的线程附加到VM。
JNI规范的以下部分提供了一些提示:
创建VM
JNI_CreateJavaVM()函数加载并初始化Java VM并返回指向JNI接口指针的指针。调用JNI_CreateJavaVM()的线程被认为是主线程。
附加到VM
JNI接口指针(JNIEnv)仅在当前线程中有效。如果另一个线程需要访问Java VM,它必须首先调用AttachCurrentThread()以将自身附加到VM并获取JNI接口指针。一旦连接到VM,本机线程就像在本机方法中运行的普通Java线程一样工作。本机线程仍然连接到VM,直到它调用DetachCurrentThread()来自行分离。
附加的线程应该有足够的堆栈空间来执行合理的工作量。每个线程的堆栈空间分配是特定于操作系统的。例如,使用pthreads,可以在pthread_create的pthread_attr_t参数中指定堆栈大小。
从VM中分离
连接到VM的本机线程必须在退出之前调用DetachCurrentThread()以自行分离。如果调用堆栈上有Java方法,则线程无法自行分离。