I need to start a new thread from native part of android application. It must be declared and defined in JNI. Does someone know how can I do it? If someone will post the example I would be very happy.
1 Answers
Easiest way is to use C++11 thread class. See this topic on how to enable C++11 with Android NDK. Also see this post if you are having problems getting thread class to work. Then you can use it like this:
#include <thread> // std::thread
void foo()
{
// do stuff...
}
void bar(int x)
{
// do stuff...
}
JNIEXPORT void JNICALL
Java_org_testjni_android_Game_someFunction(JNIEnv * env, jobject obj)
{
std::thread first (foo); // spawn new thread that calls foo()
std::thread second (bar,0); // spawn new thread that calls bar(0)
//main, foo and bar now execute concurrently
// synchronize threads:
first.join(); // pauses until first finishes
second.join(); // pauses until second finishes
}
If you can't use C++11, just use pthread (POSIX thread), which isn't much different, except it's like old C:
#include <pthread.h>
//This function will be called from a thread
void *call_from_thread(void *) {
//do stuff
return NULL;
}
JNIEXPORT void JNICALL
Java_org_testjni_android_Game_someFunction(JNIEnv * env, jobject obj)
{
pthread_t t;
//Launch a thread
pthread_create(&t, NULL, call_from_thread, NULL);
//Join the thread with the main thread
pthread_join(t, NULL);
}
Here's some more info on using POSIX threads with Android.
Also you will need to look up how to bind the JNIEnv pointer to the current thread if you want to use it in any thread but the one the JNI function is called from. From the JNI spec:
Creating the VM
The JNI_CreateJavaVM() function loads and initializes a Java VM and returns a pointer to the JNI interface pointer. The thread that called JNI_CreateJavaVM() is considered to be the main thread.
Attaching to the VM
The JNI interface pointer (JNIEnv) is valid only in the current thread. Should another thread need to access the Java VM, it must first call AttachCurrentThread() to attach itself to the VM and obtain a JNI interface pointer. Once attached to the VM, a native thread works just like an ordinary Java thread running inside a native method. The native thread remains attached to the VM until it calls DetachCurrentThread() to detach itself.
The attached thread should have enough stack space to perform a reasonable amount of work. The allocation of stack space per thread is operating system-specific. For example, using pthreads, the stack size can be specified in the pthread_attr_t argument to pthread_create.
Detaching from the VM
A native thread attached to the VM must call DetachCurrentThread() to detach itself before exiting. A thread cannot detach itself if there are Java methods on the call stack.
-
Are C++11 threads recommended over Boost threads? Or are they the same. – IgorGanapolsky Jun 01 '16 at 18:35
-
They're not the same, I believe Boost has more features. Boost threads you can interrupt like Java or .NET. Here's comparison: http://stackoverflow.com/questions/7241993/is-it-smart-to-replace-boostthread-and-boostmutex-with-c11-equivalents – Steve M Jul 14 '16 at 03:33