From c6ac461ed27ee3d510cc87a1d332f28c8f80c0e3 Mon Sep 17 00:00:00 2001 From: Assam Boudjelthia Date: Thu, 8 Aug 2024 11:32:40 +0300 Subject: [PATCH] Android: Get rid of init classes mechanism Make it more the responsibility of the module to ensure any initialization is done under JNI_OnLoad(). Qt for Android have these mechanism to set the context to Java static classes used by various modules, where the QtLoader tries to look for setContext(Context), setActivity(Activity) and setService(Service) methods defined under certain modules where it uses reflection to, for example, assign the context to them before actually loading their respective shared libraries where some initialization is needed and requires the context to be already set. This mechanism is not really necessary, since the respective libraries are going to be loaded first anyways, and they could ensure to init the context, if needed, under JNI_OnLoad() instead of those static classes and through reflection which requires the class to be public. Also, this way it would be more explicit behavior where the context is set exactly before it's needed by the module's library. Fixes: QTBUG-126478 Change-Id: I4cb39b8ef057ff7a99b66c268d85ba6da0c591ce Reviewed-by: Ville Voutilainen --- cmake/QtAndroidHelpers.cmake | 10 +--- .../org/qtproject/qt/android/QtLoader.java | 53 ------------------- src/android/templates/res/values/libs.xml | 1 - src/tools/androiddeployqt/main.cpp | 9 ---- 4 files changed, 2 insertions(+), 71 deletions(-) diff --git a/cmake/QtAndroidHelpers.cmake b/cmake/QtAndroidHelpers.cmake index 17af8c9cd88..9e81e862058 100644 --- a/cmake/QtAndroidHelpers.cmake +++ b/cmake/QtAndroidHelpers.cmake @@ -166,12 +166,9 @@ function(qt_internal_android_dependencies_content target file_content_out) if(arg_JAR_DEPENDENCIES) foreach(jar_dependency IN LISTS arg_JAR_DEPENDENCIES) section(${jar_dependency} ":" jar_file init_class) - if (init_class) - set(init_class "initClass=\"${init_class}\"") - endif() # Use unix path to allow using files on any host platform. file(TO_CMAKE_PATH ${jar_file} jar_file_unix_path) - string(APPEND file_contents "\n") + string(APPEND file_contents "\n") endforeach() endif() @@ -179,13 +176,10 @@ function(qt_internal_android_dependencies_content target file_content_out) if(arg_BUNDLED_JAR_DEPENDENCIES) foreach(jar_bundle IN LISTS arg_BUNDLED_JAR_DEPENDENCIES) section(${jar_bundle} ":" bundle_file init_class) - if (init_class) - set(init_class "initClass=\"${init_class}\"") - endif() # Use unix path to allow using files on any host platform. file(TO_CMAKE_PATH ${bundle_file} jar_bundle_unix_path) string(APPEND file_contents - "\n") + "\n") endforeach() endif() diff --git a/src/android/jar/src/org/qtproject/qt/android/QtLoader.java b/src/android/jar/src/org/qtproject/qt/android/QtLoader.java index bab9ff1d575..3e2a10555c1 100644 --- a/src/android/jar/src/org/qtproject/qt/android/QtLoader.java +++ b/src/android/jar/src/org/qtproject/qt/android/QtLoader.java @@ -70,7 +70,6 @@ abstract class QtLoader { } initClassLoader(baseContext); - initStaticClasses(baseContext); try { initContextInfo(baseContext); } catch (NameNotFoundException e) { @@ -146,45 +145,6 @@ abstract class QtLoader { return new ArrayList<>(); } - private void initStaticClasses(Context context) { - boolean isActivity = context instanceof Activity; - for (String className : getStaticInitClasses()) { - try { - Class initClass = m_classLoader.loadClass(className); - Object staticInitDataObject = initClass.newInstance(); // create an instance - - if (isActivity) { - try { - Method m = initClass.getMethod("setActivity", Activity.class, Object.class); - m.invoke(staticInitDataObject, (Activity) context, this); - } catch (InvocationTargetException | NoSuchMethodException e) { - Log.d(QtTAG, "Class " + initClass.getName() + " does not implement " + - "setActivity method"); - } - } else { - try { - Method m = initClass.getMethod("setService", Service.class, Object.class); - m.invoke(staticInitDataObject, (Service) context, this); - } catch (InvocationTargetException | NoSuchMethodException e) { - Log.d(QtTAG, "Class " + initClass.getName() + " does not implement " + - "setService method"); - } - } - - try { - // For modules that don't need/have setActivity/setService - Method m = initClass.getMethod("setContext", Context.class); - m.invoke(staticInitDataObject, context); - } catch (InvocationTargetException | NoSuchMethodException e) { - Log.d(QtTAG, "Class " + initClass.getName() + " does not implement " + - "setContext method"); - } - } catch (IllegalAccessException | ClassNotFoundException | InstantiationException e) { - Log.d(QtTAG, "Could not instantiate class " + className + ", " + e); - } - } - } - /** * Initialize the class loader instance and sets it via QtNative. * This would also be used by QJniObject API. @@ -394,19 +354,6 @@ abstract class QtLoader { return localLibs; } - @SuppressLint("DiscouragedApi") - private ArrayList getStaticInitClasses() { - int id = m_resources.getIdentifier("static_init_classes", "string", m_packageName); - String[] classes = m_resources.getString(id).split(":"); - ArrayList finalClasses = new ArrayList<>(); - for (String element : classes) { - if (!element.isEmpty()) { - finalClasses.add(element); - } - } - return finalClasses; - } - @SuppressLint("DiscouragedApi") private String[] getBundledLibs() { int id = m_resources.getIdentifier("bundled_libs", "array", m_packageName); diff --git a/src/android/templates/res/values/libs.xml b/src/android/templates/res/values/libs.xml index fe63866f726..38b0a48ea14 100644 --- a/src/android/templates/res/values/libs.xml +++ b/src/android/templates/res/values/libs.xml @@ -14,7 +14,6 @@ - diff --git a/src/tools/androiddeployqt/main.cpp b/src/tools/androiddeployqt/main.cpp index 38749db8736..e90d2d1ed64 100644 --- a/src/tools/androiddeployqt/main.cpp +++ b/src/tools/androiddeployqt/main.cpp @@ -237,7 +237,6 @@ struct Options bool usesOpenGL = false; // Per package collected information - QStringList initClasses; // permissions 'name' => 'optional additional attributes' QMap permissions; QStringList features; @@ -1789,14 +1788,10 @@ bool updateLibsXml(Options *options) allLocalLibs += " %1;%2\n"_L1.arg(it.key(), localLibs.join(u':')); } - options->initClasses.removeDuplicates(); - QHash replacements; replacements[QStringLiteral("")] += qtLibs.trimmed(); replacements[QStringLiteral("")] = allLocalLibs.trimmed(); replacements[QStringLiteral("")] = extraLibs.trimmed(); - const QString initClasses = options->initClasses.join(u':'); - replacements[QStringLiteral("")] = initClasses; // Set BUNDLE_LOCAL_QT_LIBS based on the deployment used replacements[QStringLiteral("")] @@ -2117,10 +2112,6 @@ bool readAndroidDependencyXml(Options *options, usedDependencies->insert(dependency.absolutePath); } } - - if (reader.attributes().hasAttribute("initClass"_L1)) { - options->initClasses.append(reader.attributes().value("initClass"_L1).toString()); - } } else if (reader.name() == "lib"_L1) { QString fileName = QDir::cleanPath(reader.attributes().value("file"_L1).toString()); if (reader.attributes().hasAttribute("replaces"_L1)) {