【发布时间】:2015-05-23 23:14:10
【问题描述】:
我有两个项目,比如说 projectMain 和 projectPlugin。 我有一个接口类。
这是接口类代码:
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";
}
}
然后我编译 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
然后我有一个从 jar 文件中读取来加载 jar 文件的类。这是代码:
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;
}
}
我得到如下图所示的 ClassCastException 错误:
03-20 20:53:30.453: W/System.err(15986): java.lang.ClassCastException: com.example.helloworld.plugin.PluginHelloWorld 不能转换为 com.far.lib.IPlugin 03-20 20:53:30.453: W/System.err(15986): 在 com.far.plugin.PluginManager.getPlugins(PluginManager.java:61) 03-20 20:53:30.453: W/System.err(15986): 在 com.far.exampleplugin2.MainActivity.onResume(MainActivity.java:32) 03-20 20:53:30.453: W/System.err(15986): 在 android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1192) 03-20 20:53:30.453: W/System.err(15986): 在 android.app.Activity.performResume(Activity.java:5211) 03-20 20:53:30.453: W/System.err(15986): 在 android.app.ActivityThread.performResumeActivity(ActivityThread.java:2780) 03-20 20:53:30.453: W/System.err(15986): 在 android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2819) 03-20 20:53:30.453: W/System.err(15986): 在 android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2266) 03-20 20:53:30.453: W/System.err(15986): 在 android.app.ActivityThread.access$600(ActivityThread.java:141) 03-20 20:53:30.453: W/System.err(15986): 在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256) 03-20 20:53:30.453: W/System.err(15986): 在 android.os.Handler.dispatchMessage(Handler.java:99) 03-20 20:53:30.453: W/System.err(15986): 在 android.os.Looper.loop(Looper.java:137) 03-20 20:53:30.453: W/System.err(15986): 在 android.app.ActivityThread.main(ActivityThread.java:5103) 03-20 20:53:30.453: W/System.err(15986): 在 java.lang.reflect.Method.invokeNative(Native Method) 03-20 20:53:30.453: W/System.err(15986): 在 java.lang.reflect.Method.invoke(Method.java:525) 03-20 20:53:30.453: W/System.err(15986): 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737) 03-20 20:53:30.453: W/System.err(15986): 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 03-20 20:53:30.453: W/System.err(15986): at dalvik.system.NativeStart.main(Native Method)
我用Log打印了clazz和IPlugin的每个classloader,结果不一样。这是结果:
03-20 20:56:09.253: D/test(16698): dalvik.system.DexClassLoader[DexPathList[[zip file "/storage/emulated/0/Plugin/HelloWorld1.jar"],nativeLibraryDirectories=[/系统/库]]] 03-20 20:56:09.253: D/test1(16698): dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.far.exampleplugin2-1.apk"],nativeLibraryDirectories=[/data /app-lib/com.far.exampleplugin2-1, /system/lib]]]
我在这里要问的是如何将加载的类从 projectMain 转换为接口类?
谢谢。
【问题讨论】:
标签: java android plugins interface casting