Java 如何在Android中将加载的类强制转换为接口类
我有两个项目,比如projectMain和projectPlugin。 我有一个接口类 这是接口类代码:Java 如何在Android中将加载的类强制转换为接口类,java,android,plugins,interface,casting,Java,Android,Plugins,Interface,Casting,我有两个项目,比如projectMain和projectPlugin。 我有一个接口类 这是接口类代码: package com.far.lib; public interface IPlugin { public String getNamaModul(); public String getNamaPaket(); } 我使用projectMain作为projectPlugin的库项目。 我从projectMain创建了一个实现接口类的类,下面是代码: package
package com.far.lib;
public interface IPlugin {
public String getNamaModul();
public String getNamaPaket();
}
我使用projectMain作为projectPlugin的库项目。
我从projectMain创建了一个实现接口类的类,下面是代码:
package com.example.helloworld.plugin;
public class PluginHelloWorld implements com.far.lib.IPlugin{
@Override
public String getNamaModul() {
// TODO Auto-generated method stub
return "Modul Hello World";
}
@Override
public String getNamaPaket() {
// TODO Auto-generated method stub
return "com.example.helloworld";
}
}
public class PluginManager {
public static List<PluginModel> getPlugins(Activity activty) {
List<PluginModel> plugins = new ArrayList<PluginModel>();
File pluginLoc = new File(Environment.getExternalStorageDirectory()
+ "/Plugin/");
File[] pluginList = pluginLoc.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
Log.d("file path", pathname.toString());
return pathname.getPath().toLowerCase().endsWith(".jar");
}
});
// URL[] urls = new URL[pluginList.length];
for (int i = 0; i < pluginList.length; i++) {
JarFile jarFile = null;
try {
jarFile = new JarFile(pluginList[i]);
Manifest manifest = jarFile.getManifest();
String ModuleClassName = manifest.getMainAttributes().getValue(
"Module-Class");
Log.d("test", ModuleClassName);
File DexOutputFile = activty.getDir("outdex",
Context.MODE_PRIVATE);
DexClassLoader dcl = new DexClassLoader(
pluginList[i].getAbsolutePath(),
DexOutputFile.getAbsolutePath(), null,
ClassLoader.getSystemClassLoader());
Class<?> clazz = dcl.loadClass(ModuleClassName);
// Log.d("test", clazz.getClassLoader().toString());
// Log.d("test1",IPlugin.class.getClassLoader().toString());
IPlugin temp = (IPlugin) clazz.newInstance();
plugins.add(new PluginModel(namaModul, namaPaket));
} catch (Exception e) {
e.printStackTrace();
}
}
return plugins;
}
}
然后我编译projectPlugin以获得一个apk文件,我将apk文件更改为jar文件,并在其中添加一个清单文件,清单代码如下:
Manifest-Version: 1.0
Module-Class: com.example.helloworld.plugin.PluginHelloWorld <-- this line of code is the code that i added in the manifest file
清单版本:1.0
模块类:com.example.helloworld.plugin.PluginHelloWorld如果类加载不兼容,则会发生java中兼容类的异常。如果系统类加载器未加载应用程序,则可能会发生这种情况。由于我不是安卓专家,我不确定锁定的类加载器是否是系统类加载器。因此,您可以将DexClassLoader配置为此时执行的类的类加载器this.getClass().getClassLoader()
,或希望与IPlugin.class.getClassLoader()兼容的接口之一作为父类加载器。这些是您需要兼容的类装入器<代码>线程.currentThread().getContextClassLoader()
也值得一试
DexClassLoader dcl = new DexClassLoader(
pluginList[i].getAbsolutePath(),
DexOutputFile.getAbsolutePath(), null,
IPlugin.class.getClassLoader());
我在使用您的答案时发现了新的警告和错误。警告:03-21 09:58:11.524:W/dalvikvm(2326):由意外索引解析的类:Lcom/example/helloworld/plugin/PluginHelloWorld;(0xa5465b30):0x97ee3000参考[Lcom/far/lib/IPlugin;]Lcom/far/lib/IPlugin;(0xa543e0a8):0x98015000 03-21 09:58:11.524:W/dalvikvm(2326):(Lcom/example/helloworld/plugin/PluginHelloWorld;在预验证期间使用了不同的Lcom/far/lib/IPlugin;
错误:03-21 09:52:57.308:E/AndroidRuntime(2147):java.lang.IllegalAccessError:预验证类中的类ref已解析为意外实现