Android: Fix freeze on start when the activity was destroyed before

This can be tested by enabling "Don't keep activities" in the developer
options. With this option Android will immediately destroy the activity
when it is moved to the background. In this case registerBackends will
be called the first time before the BackendRegister was created. Because
m_backendsRegistered was set to true even if it failed, the final call has
no effect. So we need to ensure to set m_backendsRegistered only if a
BackendRegister is available.

Fixes: QTBUG-132085
Pick-to: 6.9 6.8
Change-Id: I2ea1c0e0737c982594ceb06cbaf540399c45e3f4
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
This commit is contained in:
Lars Schmertmann 2024-12-25 13:41:29 +01:00
parent 3928d53003
commit 9903242eca
5 changed files with 23 additions and 2 deletions

View File

@ -4,6 +4,7 @@ package org.qtproject.qt.android;
class BackendRegister
{
static native boolean isNull();
static native void registerBackend(Class interfaceType, Object interfaceObject);
static native void unregisterBackend(Class interfaceType);
}

View File

@ -59,8 +59,9 @@ class QtActivityDelegate extends QtActivityDelegateBase
void registerBackends()
{
if (m_backendsRegistered)
if (m_backendsRegistered || BackendRegister.isNull())
return;
m_backendsRegistered = true;
BackendRegister.registerBackend(QtWindowInterface.class, QtActivityDelegate.this);
BackendRegister.registerBackend(QtAccessibilityInterface.class, QtActivityDelegate.this);
@ -74,6 +75,10 @@ class QtActivityDelegate extends QtActivityDelegateBase
return;
m_backendsRegistered = false;
if (BackendRegister.isNull())
return;
BackendRegister.unregisterBackend(QtWindowInterface.class);
BackendRegister.unregisterBackend(QtAccessibilityInterface.class);
BackendRegister.unregisterBackend(QtMenuInterface.class);

View File

@ -88,12 +88,19 @@ class QtEmbeddedDelegate extends QtActivityDelegateBase
synchronized (this) {
m_stateDetails = details;
if (details.isStarted && !m_backendsRegistered) {
if (BackendRegister.isNull())
return;
m_backendsRegistered = true;
BackendRegister.registerBackend(QtWindowInterface.class, this);
BackendRegister.registerBackend(QtMenuInterface.class, this);
BackendRegister.registerBackend(QtInputInterface.class, m_inputDelegate);
} else if (!details.isStarted && m_backendsRegistered) {
m_backendsRegistered = false;
if (BackendRegister.isNull())
return;
BackendRegister.unregisterBackend(QtWindowInterface.class);
BackendRegister.unregisterBackend(QtMenuInterface.class);
BackendRegister.unregisterBackend(QtInputInterface.class);

View File

@ -14,10 +14,16 @@ Q_DECLARE_JNI_CLASS(BackendRegister, "org/qtproject/qt/android/BackendRegister")
bool AndroidBackendRegister::registerNatives()
{
return QtJniTypes::BackendRegister::registerNativeMethods(
{ Q_JNI_NATIVE_SCOPED_METHOD(registerBackend, AndroidBackendRegister),
{ Q_JNI_NATIVE_SCOPED_METHOD(isNull, AndroidBackendRegister),
Q_JNI_NATIVE_SCOPED_METHOD(registerBackend, AndroidBackendRegister),
Q_JNI_NATIVE_SCOPED_METHOD(unregisterBackend, AndroidBackendRegister) });
}
jboolean AndroidBackendRegister::isNull(JNIEnv *, jclass)
{
return QtAndroid::backendRegister() == nullptr;
}
void AndroidBackendRegister::registerBackend(JNIEnv *, jclass, jclass interfaceClass,
jobject interface)
{

View File

@ -60,6 +60,8 @@ private:
QMutex m_registerMutex;
QMap<QString, QJniObject> m_register;
static jboolean isNull(JNIEnv *, jclass);
Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(isNull)
static void registerBackend(JNIEnv *, jclass, jclass interfaceClass, jobject interface);
Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(registerBackend)
static void unregisterBackend(JNIEnv *, jclass, jclass interfaceClass);