Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Mobile and Embedded
  4. [Solved] How to pass by reference a QAndroidJniEnvironment object to a Qthread?
QtWS25 Last Chance

[Solved] How to pass by reference a QAndroidJniEnvironment object to a Qthread?

Scheduled Pinned Locked Moved Mobile and Embedded
androidqthread
7 Posts 3 Posters 3.1k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    a.toraby
    wrote on last edited by a.toraby
    #1

    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.

    1 Reply Last reply
    0
    • sneubertS Offline
      sneubertS Offline
      sneubert
      wrote on last edited by
      #2

      To use an jni environment pointer by a different thread you have to call AttachCurrentThread.

      A 1 Reply Last reply
      1
      • sneubertS sneubert

        To use an jni environment pointer by a different thread you have to call AttachCurrentThread.

        A Offline
        A Offline
        a.toraby
        wrote on last edited by a.toraby
        #3

        @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)
        
        J 2 Replies Last reply
        0
        • A a.toraby

          @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)
          
          J Offline
          J Offline
          jalomic
          wrote on last edited by
          #4

          @a.toraby
          _jvm and _jniENV are initialised ?

          1 Reply Last reply
          1
          • sneubertS Offline
            sneubertS Offline
            sneubert
            wrote on last edited by
            #5

            _jniENV is a pointer already so try to pass it without & to AttachCurrentThread

            1 Reply Last reply
            1
            • A a.toraby

              @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)
              
              J Offline
              J Offline
              jalomic
              wrote on last edited by
              #6

              @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

              A 1 Reply Last reply
              1
              • J jalomic

                @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

                A Offline
                A Offline
                a.toraby
                wrote on last edited by
                #7

                @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();
                }
                
                1 Reply Last reply
                0

                • Login

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved