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 <ville.voutilainen@qt.io>
This commit is contained in:
parent
c49aeeceff
commit
c6ac461ed2
@ -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 "<jar file=\"${jar_file_unix_path}\" ${init_class} />\n")
|
||||
string(APPEND file_contents "<jar file=\"${jar_file_unix_path}\" />\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
|
||||
"<jar bundling=\"1\" file=\"${jar_bundle_unix_path}\" ${init_class} />\n")
|
||||
"<jar bundling=\"1\" file=\"${jar_bundle_unix_path}\" />\n")
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
|
@ -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<String> getStaticInitClasses() {
|
||||
int id = m_resources.getIdentifier("static_init_classes", "string", m_packageName);
|
||||
String[] classes = m_resources.getString(id).split(":");
|
||||
ArrayList<String> 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);
|
||||
|
@ -14,7 +14,6 @@
|
||||
<!-- %%INSERT_LOCAL_LIBS%% -->
|
||||
</array>
|
||||
|
||||
<string name="static_init_classes"><!-- %%INSERT_INIT_CLASSES%% --></string>
|
||||
<string name="use_local_qt_libs"><!-- %%USE_LOCAL_QT_LIBS%% --></string>
|
||||
<string name="bundle_local_qt_libs"><!-- %%BUNDLE_LOCAL_QT_LIBS%% --></string>
|
||||
<string name="system_libs_prefix"><!-- %%SYSTEM_LIBS_PREFIX%% --></string>
|
||||
|
@ -237,7 +237,6 @@ struct Options
|
||||
bool usesOpenGL = false;
|
||||
|
||||
// Per package collected information
|
||||
QStringList initClasses;
|
||||
// permissions 'name' => 'optional additional attributes'
|
||||
QMap<QString, QString> permissions;
|
||||
QStringList features;
|
||||
@ -1789,14 +1788,10 @@ bool updateLibsXml(Options *options)
|
||||
allLocalLibs += " <item>%1;%2</item>\n"_L1.arg(it.key(), localLibs.join(u':'));
|
||||
}
|
||||
|
||||
options->initClasses.removeDuplicates();
|
||||
|
||||
QHash<QString, QString> replacements;
|
||||
replacements[QStringLiteral("<!-- %%INSERT_QT_LIBS%% -->")] += qtLibs.trimmed();
|
||||
replacements[QStringLiteral("<!-- %%INSERT_LOCAL_LIBS%% -->")] = allLocalLibs.trimmed();
|
||||
replacements[QStringLiteral("<!-- %%INSERT_EXTRA_LIBS%% -->")] = extraLibs.trimmed();
|
||||
const QString initClasses = options->initClasses.join(u':');
|
||||
replacements[QStringLiteral("<!-- %%INSERT_INIT_CLASSES%% -->")] = initClasses;
|
||||
|
||||
// Set BUNDLE_LOCAL_QT_LIBS based on the deployment used
|
||||
replacements[QStringLiteral("<!-- %%BUNDLE_LOCAL_QT_LIBS%% -->")]
|
||||
@ -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)) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user