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>bb10
parent
e066172c49
commit
24a0d958a7
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -58,13 +62,6 @@ abstract class QtLoader {
|
|||
initContextInfo();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
|
|
@ -72,10 +69,29 @@ abstract class QtLoader {
|
|||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,35 +5,19 @@
|
|||
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)
|
||||
|
|
@ -41,14 +25,4 @@ class QtServiceLoader extends QtLoader {
|
|||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue