{Apologies for the cross-post with android-developers forum. Haven\'t received any answers there}
I have an interesting design challenge:
I have a fro
Within your native code, you can use JNI to obtain classes (and objects) from your VM, and once you've got a class (or object) you can locate methods and call them (static methods for a class, all methods for an object). It seems to me that the simple solution is to provide a helper in your java class which encapsulates the native methods and have the native code call into it.
In the past, I've needed to have native code determine if its thread has been interrupted at the Java level. Java provides java.lang.Thread.currentThread() as a static to find your own thread, and java.lang.Thread.isInterrupted() to [non-destructively] determine the interrupted status. I used the following to solve this problem at the native level; perhaps you can use it towards your needs (with appropriate adaptation to message sending, of course):
/* JavaThread: this class is a simple wrapper to be used around */
/* JNI's Thread class. It locates the provided functions as needed */
/* and when it is destroyed (such as going out of scope) it will */
/* release its local references. */
class JavaThread
{
public:
JavaThread(JNIEnv *env)
{
mEnv = env;
/* find the Java Thread class within the JVM: */
mThread = mEnv->FindClass("java/lang/Thread");
/* find the Thread.currentThread() method within the JVM: */
mCurrentThreadMID = mEnv->GetStaticMethodID(mThread, "currentThread", "()Ljava/lang/Thread;");
/* find the current thread's isInterrupted() method: */
mIsInterruptedMID = mEnv->GetMethodID(mThread, "isInterrupted", "()Z");
}
~JavaThread()
{
if (mThread)
{
mEnv->DeleteLocalRef(mThread);
mThread = 0;
}
}
bool isInterrupted() {
bool bResult;
if (!mThread) return false;
if (!mIsInterruptedMID) return false;
/* find the current thread (from the JVM's perspective): */
jobject jCurrentThread = (jobject)mEnv->CallStaticObjectMethod(mThread, mCurrentThreadMID);
if (NULL == jCurrentThread) return false;
/* see if the current thread is interrupted */
bResult = (bool)mEnv->CallBooleanMethod(jCurrentThread, mIsInterruptedMID);
/* delete the current thread reference */
mEnv->DeleteLocalRef(jCurrentThread);
/* and return the result */
return bResult;
}
private:
JNIEnv *mEnv;
jclass mThread;
jmethodID mCurrentThreadMID;
jmethodID mIsInterruptedMID;
};
Instantiation is based on the JNIEnv * provided to your native method, and a simple allocate/call/deallocate line of code to call the isInterrupted() method is:
if (JavaThread(env).isInterrupted()) { ... }