[Solved] How to pass by reference a QAndroidJniEnvironment object to a Qthread?
-
I have a thread object that works In the qt main thread I successfully can run this:
jbyteArray jBuffer = _env->NewByteArray(bufferSize);
The _env is a QAndroidJniEnvironment. but If I try to use _env in the run function of a Runnable, the application crashes and this error occurs:
Fatal signal 11 (SIGSEGV), code 1
This is the code:
class HelloWorldTask : public QRunnable { QAndroidJniEnvironment * _env; void run() { qDebug() << "Hello world from thread" << QThread::currentThread(); jbyteArray jBuffer = (*_env)->NewByteArray(10); qDebug() << "Hello 2 world from thread" << QThread::currentThread(); } public: void setPointer(QAndroidJniEnvironment * p){ _env = p; } }; int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); HelloWorldTask * hello = new HelloWorldTask(); QAndroidJniEnvironment env; QAndroidJniEnvironment * p = & env; hello->setPointer(p); QThreadPool::globalInstance()->start(hello); return a.exec(); }
Could you please tell me how can I use the pointer to the QAndroidJniEnvironment or QAndroidJniObject in a new Qthread? so the application ui remains responsive during the execution of java process.
-
To use an jni environment pointer by a different thread you have to call AttachCurrentThread.
@sneubert
Thanks for your reply. I tried he following code but I got fatal signal again!JavaVM * _jvm = 0; JNIEnv* _jniENV; qDebug() << "Attaching current thread"; _jvm->AttachCurrentThread(&_jniENV,NULL);
Here is full error description:
D/Qt (14352): ..\untitled4\main.cpp:47 (int main(int, char**)): Attaching current thread F/libc (14352): Fatal signal 11 (SIGSEGV), code 1, fault addr 0x0 in tid 14508 (QtThread)
-
@sneubert
Thanks for your reply. I tried he following code but I got fatal signal again!JavaVM * _jvm = 0; JNIEnv* _jniENV; qDebug() << "Attaching current thread"; _jvm->AttachCurrentThread(&_jniENV,NULL);
Here is full error description:
D/Qt (14352): ..\untitled4\main.cpp:47 (int main(int, char**)): Attaching current thread F/libc (14352): Fatal signal 11 (SIGSEGV), code 1, fault addr 0x0 in tid 14508 (QtThread)
-
@sneubert
Thanks for your reply. I tried he following code but I got fatal signal again!JavaVM * _jvm = 0; JNIEnv* _jniENV; qDebug() << "Attaching current thread"; _jvm->AttachCurrentThread(&_jniENV,NULL);
Here is full error description:
D/Qt (14352): ..\untitled4\main.cpp:47 (int main(int, char**)): Attaching current thread F/libc (14352): Fatal signal 11 (SIGSEGV), code 1, fault addr 0x0 in tid 14508 (QtThread)
-
@a.toraby said:
JavaVM * _jvm = 0;
JNIEnv* _jniENV;
qDebug() << "Attaching current thread";
_jvm->AttachCurrentThread(&_jniENV,NULL);As i see here _jvm - is a null pointer.. and you call method from null pointer
@jalomic said:
@a.toraby said:
JavaVM * _jvm = 0;
JNIEnv* _jniENV;
qDebug() << "Attaching current thread";
_jvm->AttachCurrentThread(&_jniENV,NULL);As i see here _jvm - is a null pointer.. and you call method from null pointer
Yes you are right. I solved it by using a QAndroidJniEnvironment: Here is the working code:
class HelloWorldTask : public QRunnable { QAndroidJniEnvironment * _env; void run() { JNIEnv * jniEnv; JavaVM * jvm = _env->javaVM(); qDebug() << "Getting jni environment"; jvm->GetEnv(reinterpret_cast<void**>(&_env), JNI_VERSION_1_6); qDebug() << "Attaching current thread"; jvm->AttachCurrentThread(&jniEnv,NULL); qDebug() << "Creating byte array" ; jbyteArray jBuffer = jniEnv->NewByteArray(10); qDebug() << "byte array created" ; jvm->DetachCurrentThread(); } public: void setPointer(QAndroidJniEnvironment * p){ _env = p; } }; int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); HelloWorldTask * hello = new HelloWorldTask(); QAndroidJniEnvironment * env; hello->setPointer(env); // QThreadPool takes ownership and deletes 'hello' automatically QThreadPool::globalInstance()->start(hello); return a.exec(); }