diff --git a/src/plugins/platforms/android/qandroidplatformwindow.cpp b/src/plugins/platforms/android/qandroidplatformwindow.cpp index 4c76bfb3d48..1362b7d3929 100644 --- a/src/plugins/platforms/android/qandroidplatformwindow.cpp +++ b/src/plugins/platforms/android/qandroidplatformwindow.cpp @@ -96,6 +96,7 @@ void QAndroidPlatformWindow::initialize() QAndroidPlatformWindow::~QAndroidPlatformWindow() { + const auto guard = destructionGuard(); if (window()->isTopLevel()) platformScreen()->removeWindow(this); } @@ -353,6 +354,9 @@ void QAndroidPlatformWindow::setSurface(JNIEnv *env, jobject object, jint window continue; QAndroidPlatformWindow *platformWindow = static_cast(window->handle()); + const auto guard = platformWindow->destructionGuard(); + if (!platformWindow->m_surfaceCreated) + continue; if (platformWindow->nativeViewId() == windowId) platformWindow->onSurfaceChanged(surface); } @@ -373,6 +377,18 @@ void QAndroidPlatformWindow::windowFocusChanged(JNIEnv *env, jobject object, } } +/* + Due to calls originating from Android, it is possible for native methods to + try to manipulate any given instance of QAndroidPlatformWindow when it is + already being destroyed. So we use this to guard against that. It is called + in the destructor, and should also be called in any function registered to + be called from java that may touch an instance of QAndroidPlatformWindow. + */ +QMutexLocker QAndroidPlatformWindow::destructionGuard() +{ + return QMutexLocker(&m_destructionMutex); +} + bool QAndroidPlatformWindow::registerNatives(QJniEnvironment &env) { if (!env.registerNativeMethods(QtJniTypes::Traits::className(), diff --git a/src/plugins/platforms/android/qandroidplatformwindow.h b/src/plugins/platforms/android/qandroidplatformwindow.h index d3822e2d96e..ef4e799a75e 100644 --- a/src/plugins/platforms/android/qandroidplatformwindow.h +++ b/src/plugins/platforms/android/qandroidplatformwindow.h @@ -96,12 +96,15 @@ protected: QWaitCondition m_surfaceWaitCondition; bool m_surfaceCreated = false; QMutex m_surfaceMutex; + QMutex m_destructionMutex; private: static void setSurface(JNIEnv *env, jobject obj, jint windowId, QtJniTypes::Surface surface); Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(setSurface) static void windowFocusChanged(JNIEnv *env, jobject object, jboolean focus, jint windowId); Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(windowFocusChanged) + + [[nodiscard]] QMutexLocker destructionGuard(); }; QT_END_NAMESPACE