Android ClassLoader:如果 class 实现接口,则 loadClass 失败
Android ClassLoader: loadClass fails if the class implements an interface
我正在使用以下代码从外部包动态加载 class:
Object plugin = null;
String packageName = "unipd.elia.deltapluginaccelerometersensor";
String className = "unipd.elia.deltapluginaccelerometersensor.AccelerometerPlugin";
try {
PackageManager packageManager = getPackageManager();
ApplicationInfo appInfo = packageManager.getApplicationInfo(packageName, 0);
DexFile df = new DexFile(appInfo.sourceDir);
ClassLoader cl = getClassLoader();
Class classToInvestigate = df.loadClass(className, cl);
plugin = classToInvestigate.newInstance();
} catch (Exception e) {
System.out.println("EXCEPTION");
}
问题如下:如果我尝试加载的 class 是 "simple" class 一切正常,但如果它实现了一个接口,加载就会失败。这是无法加载的 class 示例:
package unipd.elia.deltapluginaccelerometersensor;
public class AccelerometerPlugin implements IDeltaPlugin {
@Override
public String getPluginName() {
return "Accelerometer Sensor Plugin";
}
@Override
public String getPluginID() {
return "delta.plugin.accelerometersensor";
}
@Override
public String getPluginAuthor() {
return "Me";
}
}
及其实现的接口:
public interface IDeltaPlugin {
String getPluginName();
String getPluginID();
String getPluginAuthor();
}
基本上,如果 class 实现接口,则对 loadClass()
returns 的调用为 null。删除 "implements" 语句,它加载正常。
我做错了什么?
好吧,原来问题是有问题的接口在一个 Android 库项目中,该项目由执行加载的应用程序和 class 要加载的 apk 共享定义。
ClassLoader 然后会感到困惑,因为它在 class 路径中找到同一接口的两个副本。
解决方法:将共享库转为JAR库,在插件apk中以"provided"(而不是"compile")方式导入。这样只有一个接口副本存在(apk 中正在进行 class 加载的那个)
我正在使用以下代码从外部包动态加载 class:
Object plugin = null;
String packageName = "unipd.elia.deltapluginaccelerometersensor";
String className = "unipd.elia.deltapluginaccelerometersensor.AccelerometerPlugin";
try {
PackageManager packageManager = getPackageManager();
ApplicationInfo appInfo = packageManager.getApplicationInfo(packageName, 0);
DexFile df = new DexFile(appInfo.sourceDir);
ClassLoader cl = getClassLoader();
Class classToInvestigate = df.loadClass(className, cl);
plugin = classToInvestigate.newInstance();
} catch (Exception e) {
System.out.println("EXCEPTION");
}
问题如下:如果我尝试加载的 class 是 "simple" class 一切正常,但如果它实现了一个接口,加载就会失败。这是无法加载的 class 示例:
package unipd.elia.deltapluginaccelerometersensor;
public class AccelerometerPlugin implements IDeltaPlugin {
@Override
public String getPluginName() {
return "Accelerometer Sensor Plugin";
}
@Override
public String getPluginID() {
return "delta.plugin.accelerometersensor";
}
@Override
public String getPluginAuthor() {
return "Me";
}
}
及其实现的接口:
public interface IDeltaPlugin {
String getPluginName();
String getPluginID();
String getPluginAuthor();
}
基本上,如果 class 实现接口,则对 loadClass()
returns 的调用为 null。删除 "implements" 语句,它加载正常。
我做错了什么?
好吧,原来问题是有问题的接口在一个 Android 库项目中,该项目由执行加载的应用程序和 class 要加载的 apk 共享定义。
ClassLoader 然后会感到困惑,因为它在 class 路径中找到同一接口的两个副本。
解决方法:将共享库转为JAR库,在插件apk中以"provided"(而不是"compile")方式导入。这样只有一个接口副本存在(apk 中正在进行 class 加载的那个)