summaryrefslogtreecommitdiffstats
path: root/src/android/jar
diff options
context:
space:
mode:
authorTinja Paavoseppä <tinja.paavoseppa@qt.io>2024-01-11 09:57:20 +0200
committerTinja Paavoseppä <tinja.paavoseppa@qt.io>2024-01-24 13:20:18 +0200
commit24a0d958a72e94c3e39b3a995ca0b2789b942dbe (patch)
treec3cf2c8b19acac1dc77f64032d617a65bfe92f0e /src/android/jar
parente066172c49173141cd72aa40f127213065100527 (diff)
Android: Let QtLoader handle different Contexts when initializing
QtLoader now calls the correct methods when initializing static classes and retrieving ContextInfo based on the type of the Context (Activity or Service). This is done to avoid the need for code duplication when introducing other QtLoader sub classes that deal with the same Context types, such as the loader for the use case where Qt is used from a native Android app. Abstract methods and their implementations in subclasses aimed at handling this removed as a result. Pick-to: 6.7 Change-Id: I6cda8e4733594a6a3963cf0fd8217de2fbd408f8 Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
Diffstat (limited to 'src/android/jar')
-rw-r--r--src/android/jar/src/org/qtproject/qt/android/QtActivityLoader.java24
-rw-r--r--src/android/jar/src/org/qtproject/qt/android/QtLoader.java75
-rw-r--r--src/android/jar/src/org/qtproject/qt/android/QtServiceLoader.java30
3 files changed, 61 insertions, 68 deletions
diff --git a/src/android/jar/src/org/qtproject/qt/android/QtActivityLoader.java b/src/android/jar/src/org/qtproject/qt/android/QtActivityLoader.java
index 1b5eac55ed..0a14cefaf7 100644
--- a/src/android/jar/src/org/qtproject/qt/android/QtActivityLoader.java
+++ b/src/android/jar/src/org/qtproject/qt/android/QtActivityLoader.java
@@ -8,6 +8,7 @@ import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
+import android.content.ContextWrapper;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
@@ -26,23 +27,12 @@ class QtActivityLoader extends QtLoader {
public QtActivityLoader(Activity activity)
{
- super(activity);
+ super(new ContextWrapper(activity));
m_activity = activity;
extractContextMetaData();
}
- @Override
- protected void initContextInfo() {
- try {
- m_contextInfo = m_context.getPackageManager().getActivityInfo(
- ((Activity)m_context).getComponentName(), PackageManager.GET_META_DATA);
- } catch (PackageManager.NameNotFoundException e) {
- e.printStackTrace();
- finish();
- }
- }
-
private void showErrorDialog() {
if (m_activity == null) {
Log.w(QtTAG, "cannot show the error dialog from a null activity object");
@@ -69,16 +59,6 @@ class QtActivityLoader extends QtLoader {
m_activity.finish();
}
- @Override
- protected void initStaticClassesImpl(Class<?> initClass, Object staticInitDataObject) {
- try {
- Method m = initClass.getMethod("setActivity", Activity.class, Object.class);
- m.invoke(staticInitDataObject, m_activity, this);
- } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
- Log.d(QtTAG, "Class " + initClass.getName() + " does not implement setActivity method");
- }
- }
-
private String getDecodedUtfString(String str)
{
byte[] decodedExtraEnvVars = Base64.decode(str, Base64.DEFAULT);
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 14059f4f3f..e8b245f0aa 100644
--- a/src/android/jar/src/org/qtproject/qt/android/QtLoader.java
+++ b/src/android/jar/src/org/qtproject/qt/android/QtLoader.java
@@ -5,9 +5,13 @@
package org.qtproject.qt.android;
import android.annotation.SuppressLint;
+import android.app.Activity;
+import android.app.Service;
+import android.content.ComponentName;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
import android.content.pm.ComponentInfo;
import android.content.res.Resources;
import android.os.Build;
@@ -59,23 +63,35 @@ abstract class QtLoader {
}
/**
- * Initializes the context info instance which is used to retrieve
- * the app metadata from the AndroidManifest.xml or other xml resources.
- * Some values are dependent on the context being an Activity or Service.
- **/
- abstract protected void initContextInfo();
-
- /**
* Implements the logic for finish the extended context, mostly called
* in error cases.
**/
abstract protected void finish();
/**
- * Context specific (Activity/Service) implementation for static classes.
- * The Activity and Service loaders call different methods.
+ * Initializes the context info instance which is used to retrieve
+ * the app metadata from the AndroidManifest.xml or other xml resources.
+ * Some values are dependent on the context being an Activity or Service.
**/
- abstract protected void initStaticClassesImpl(Class<?> initClass, Object staticInitDataObject);
+ protected void initContextInfo() {
+ try {
+ Context context = m_context.getBaseContext();
+ if (context instanceof Activity) {
+ m_contextInfo = context.getPackageManager().getActivityInfo(
+ ((Activity)context).getComponentName(), PackageManager.GET_META_DATA);
+ } else if (context instanceof Service) {
+ m_contextInfo = context.getPackageManager().getServiceInfo(
+ new ComponentName(context, context.getClass()),
+ PackageManager.GET_META_DATA);
+ } else {
+ Log.w(QtTAG, "Context is not an instance of Activity or Service, could not get " +
+ "context info for it");
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ finish();
+ }
+ }
/**
* Extract the common metadata in the base implementation. And the extended methods
@@ -123,18 +139,41 @@ abstract class QtLoader {
}
private void initStaticClasses() {
+ Context context = m_context.getBaseContext();
+ boolean isActivity = context instanceof Activity;
for (String className : getStaticInitClasses()) {
try {
Class<?> initClass = m_classLoader.loadClass(className);
Object staticInitDataObject = initClass.newInstance(); // create an instance
- initStaticClassesImpl(initClass, staticInitDataObject);
-
- // For modules that don't need/have setActivity/setService
- Method m = initClass.getMethod("setContext", Context.class);
- m.invoke(staticInitDataObject, m_context);
- } catch (ClassNotFoundException | IllegalAccessException | InstantiationException |
- NoSuchMethodException | InvocationTargetException e) {
- Log.d(QtTAG, "Class " + className + " does not implement setContext method");
+
+ 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);
}
}
}
diff --git a/src/android/jar/src/org/qtproject/qt/android/QtServiceLoader.java b/src/android/jar/src/org/qtproject/qt/android/QtServiceLoader.java
index f54627466d..f5b0bf4af9 100644
--- a/src/android/jar/src/org/qtproject/qt/android/QtServiceLoader.java
+++ b/src/android/jar/src/org/qtproject/qt/android/QtServiceLoader.java
@@ -5,50 +5,24 @@
package org.qtproject.qt.android;
import android.app.Service;
-import android.content.ComponentName;
-import android.content.pm.PackageManager;
+import android.content.ContextWrapper;
import android.util.Log;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
class QtServiceLoader extends QtLoader {
private final Service m_service;
public QtServiceLoader(Service service) {
- super(service);
+ super(new ContextWrapper(service));
m_service = service;
extractContextMetaData();
}
@Override
- protected void initContextInfo() {
- try {
- m_contextInfo = m_context.getPackageManager().getServiceInfo(
- new ComponentName(m_context, m_context.getClass()),
- PackageManager.GET_META_DATA);
- } catch (Exception e) {
- e.printStackTrace();
- finish();
- }
- }
-
- @Override
protected void finish() {
if (m_service != null)
m_service.stopSelf();
else
Log.w(QtTAG, "finish() called when service object is null");
}
-
- @Override
- protected void initStaticClassesImpl(Class<?> initClass, Object staticInitDataObject) {
- try {
- Method m = initClass.getMethod("setService", Service.class, Object.class);
- m.invoke(staticInitDataObject, m_service, this);
- } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
- Log.d(QtTAG, "Class " + initClass.getName() + " does not implement setService method");
- }
- }
}