【问题标题】:How to use QAndroidJniEnvironment pointer in a Qthread?如何在 Qthread 中使用 QAndroidJniEnvironment 指针?
【发布时间】:2015-03-15 06:42:08
【问题描述】:

在 qt 主线程中我可以成功运行这个:

 jbyteArray jBuffer = _env->NewByteArray(bufferSize);

_envQAndroidJniEnvironment。但如果我尝试在QRunnable 的运行函数中使用_env,应用程序崩溃并出现此错误:

Fatal signal 11 (SIGSEGV), code 1

这是代码:

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();
}

您能否告诉我如何在新的 Qthread 中使用指向 QAndroidJniEnvironmentQAndroidJniObject 的指针?因此应用程序 ui 在执行 java 进程期间保持响应。

【问题讨论】:

    标签: qt qthread qtandroidextras


    【解决方案1】:

    到目前为止,只有 15 人阅读了此问题。仍然没有答案。我是一个很难或很容易回答的问题! 无论如何,我在 qt 论坛用户的帮助下找到了解决方案。这是工作代码:

    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();
    }
    

    您应该调用 AttachCurrentThread 以在另一个线程中使用 jni 环境指针。我希望这对某人有所帮助。

    【讨论】:

    • a QAndroidJniEnvironment 附加了它创建的线程(如果需要),所以你不应该在线程之间移动它。如果您需要附加另一个线程,只需在该线程上创建一个新的 QAndroidJniEnvironment 实例。
    • QAndroidJniEnvironment * env;此处使用的非初始化指针:_env->javaVM();这段代码真的可以运行吗?
    猜你喜欢
    • 1970-01-01
    • 2020-11-20
    • 2017-03-12
    • 1970-01-01
    • 1970-01-01
    • 2020-02-08
    • 1970-01-01
    • 2010-09-25
    • 1970-01-01
    相关资源
    最近更新 更多