diff --git a/src/corelib/platform/android/qandroiditemmodelproxy.cpp b/src/corelib/platform/android/qandroiditemmodelproxy.cpp index 260e131fad1..cba8420dd91 100644 --- a/src/corelib/platform/android/qandroiditemmodelproxy.cpp +++ b/src/corelib/platform/android/qandroiditemmodelproxy.cpp @@ -5,6 +5,8 @@ #include #include +#include + QT_BEGIN_NAMESPACE using namespace QtJniTypes; @@ -131,7 +133,12 @@ QAndroidItemModelProxy::createNativeProxy(QJniObject itemModel) { QAbstractItemModel *nativeProxy = nativeInstance(itemModel); if (!nativeProxy) { + Q_ASSERT(QCoreApplication::instance()); + nativeProxy = new QAndroidItemModelProxy(itemModel); + QThread *qtMainThread = QCoreApplication::instance()->thread(); + if (nativeProxy->thread() != qtMainThread) + nativeProxy->moveToThread(qtMainThread); itemModel.callMethod("setNativeReference", reinterpret_cast(nativeProxy)); connect(nativeProxy, &QAndroidItemModelProxy::destroyed, nativeProxy, [](QObject *obj) { @@ -205,7 +212,8 @@ jobject QAndroidItemModelProxy::jni_createIndex(JNIEnv *env, jobject object, jin { QModelIndex (QAndroidItemModelProxy::*createIndexPtr)(int, int, quintptr) const = &QAndroidItemModelProxy::createIndex; - const QModelIndex index = invokeNativeProxyMethod(env, object, createIndexPtr, row, column, id); + const QModelIndex index = + invokeNativeProxyMethod(env, object, createIndexPtr, row, column, quintptr(id)); return env->NewLocalRef(QAndroidModelIndexProxy::jInstance(index).object()); } diff --git a/src/corelib/platform/android/qandroiditemmodelproxy_p.h b/src/corelib/platform/android/qandroiditemmodelproxy_p.h index 241f4966b13..9f5369af47a 100644 --- a/src/corelib/platform/android/qandroiditemmodelproxy_p.h +++ b/src/corelib/platform/android/qandroiditemmodelproxy_p.h @@ -21,6 +21,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE @@ -58,34 +59,58 @@ class Q_CORE_EXPORT QAndroidItemModelProxy : public QAbstractItemModel static QJniObject createProxy(QAbstractItemModel *abstractClass); template - static auto invokeNativeProxyMethod(JNIEnv */*env*/, jobject jvmObject, Func func, Args &&...args) + static auto invokeNativeProxyMethod(JNIEnv * /*env*/, jobject jvmObject, Func &&func, + Args &&...args) { Q_ASSERT(jvmObject); auto model = qobject_cast(nativeInstance(jvmObject)); Q_ASSERT(model); - return std::invoke(func, model, std::forward(args)...); + return safeCall(model, std::forward(func), std::forward(args)...); } template - static auto invokeNativeMethod(JNIEnv */*env*/, jobject jvmObject, Func func, Args &&...args) + static auto invokeNativeMethod(JNIEnv * /*env*/, jobject jvmObject, Func &&func, Args &&...args) { Q_ASSERT(jvmObject); auto model = nativeInstance(jvmObject); Q_ASSERT(model); - return std::invoke(func, model, std::forward(args)...); + return safeCall(model, std::forward(func), std::forward(args)...); } template - static auto invokeNativeImpl(JNIEnv */*env*/, jobject jvmObject, Func1 defaultFunc, Func2 func, - Args &&...args) + static auto invokeNativeImpl(JNIEnv * /*env*/, jobject jvmObject, Func1 &&defaultFunc, + Func2 &&func, Args &&...args) { Q_ASSERT(jvmObject); auto nativeModel = nativeInstance(jvmObject); auto nativeProxyModel = qobject_cast(nativeModel); if (nativeProxyModel) - return std::invoke(defaultFunc, nativeProxyModel, std::forward(args)...); + return safeCall(nativeProxyModel, std::forward(defaultFunc), + std::forward(args)...); else - return std::invoke(func, nativeModel, std::forward(args)...); + return safeCall(nativeModel, std::forward(func), std::forward(args)...); + } + + template + static auto safeCall(Object *object, Func &&func, Args &&...args) + { + using ReturnType = decltype(std::invoke(std::forward(func), object, + std::forward(args)...)); + + if constexpr (std::is_void_v) { + QMetaObject::invokeMethod(object, std::forward(func), Qt::AutoConnection, + std::forward(args)...); + } else { + ReturnType returnValue; + + const auto connectionType = object->thread() == QThread::currentThread() + ? Qt::DirectConnection + : Qt::BlockingQueuedConnection; + + QMetaObject::invokeMethod(object, std::forward(func), connectionType, + qReturnArg(returnValue), std::forward(args)...); + return returnValue; + } } static jint jni_columnCount(JNIEnv *env, jobject object, JQtModelIndex parent);