Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to start a new thread from JNI

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.

like image 804
theroom101 Avatar asked May 26 '14 14:05

theroom101


People also ask

Is JNI thread safe?

The JNI interface pointer (JNIEnv *) is only valid in the current thread. You must not pass the interface pointer from one thread to another, or cache an interface pointer and use it in multiple threads.

What is JNI and how it works?

JNI is the Java Native Interface. It defines a way for the bytecode that Android compiles from managed code (written in the Java or Kotlin programming languages) to interact with native code (written in C/C++).

What is NDK and JNI?

JNI is just the way that Java handles calling into native/C++ code, and calling back into Java from there. It has nothing to say about Android - it is a Java language feature. The Android NDK is a way to write Android applications using code called by JNI.

What is JNIEnv?

JNIEnv – a structure containing methods that we can use our native code to access Java elements. JavaVM – a structure that lets us manipulate a running JVM (or even start a new one) adding threads to it, destroying it, etc…


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.

like image 106
Steve M Avatar answered Oct 06 '22 04:10

Steve M