[Android讨论] 如何在两个应用之间共用一个接口?请教一个自定义ClassLoader
小弟现正开发一个这样一个应用,这个应用做为主应用,只需要实现一些基本的功能就行,
如果要扩展功能的话,就通过开发一些小插件来实现
实现原理是这样的:
主应用(Host)定义一个接口:
public abstract interface IExtension{
void method1(WebView webview,....);
void method2();
}
public class AbstractExtension extends ContextWrapper implements IExtension{
.....
基本是对IExtension的空实现
}
这里应用反射来实例化一个插件:
ClassLoader localExtensionClassLoader = context.createPackageContext(this.mPackageName,Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY).getClassLoader();
ClassLoader localSystemClassLoader = OlivePackageManager.getSystemClassLoader();
ClassLoaderWrapper localClassLoaderWrapper = new ClassLoaderWrapper(localExtensionClassLoader, localSystemClassLoader);
String localClassName = String.valueOf(this.mPackageName) + ".Extension";
Class<?> localClass = localClassLoaderWrapper.loadClass(localClassName);
Constructor<?> localConstructor = localClass.getConstructor( new Class[]{Context.class} );
localConstructor.setAccessible(true);
Object instance = localConstructor.newInstance( new Object[]{context} );
public class ClassLoaderWrapper extends ClassLoader{
public ClassLoaderWrapper(ClassLoader extensionClassLoader, ClassLoader systemClassLoader) {
super(systemClassLoader);
this.mLoader = extensionClassLoader;
}
protected Class<?> findClass(String className) throws ClassNotFoundException {
System.out.println("mLoader type === " + mLoader.toString());
Class<?> localClass = null;
if (localClass == null){
//这个地方,就是这个地方,加载失败
localClass = this.mLoader.loadClass(className);
}
System.out.println("mLoader.loadClass============="+localClass);
return localClass;
}
protected Class<?> loadClass(String className, boolean paramBoolean){
Class<?> localClass = null;
try {
localClass = getParent().loadClass(className);
} catch (ClassNotFoundException localClassNotFoundException) {
localClass = findLoadedClass(className);
if (localClass == null) {
try {
localClass = findClass(className);
} catch (ClassNotFoundException e) {
}
}
}
return localClass;
}
}
====================华丽的分界线===============================
在插件工程中:
public class Extension extends AbstractExtension{
...实现IExtension接口
}
这样做的话,插件工程必须加入对主工程(Host)的引用
思想是好的,但是问题出来了,我主应用的类加载器总是load不到插件工程的Extension类,
但是如果我的插件工程里面不extends AbstractExtension 的话,是ok的,但是不继承,就失去了意义。
分析原因:
public ClassLoaderWrapper(ClassLoader extensionClassLoader, ClassLoader systemClassLoader) {
super(systemClassLoader);
this.mLoader = extensionClassLoader;
}
这个构造函数里面,extensionClassLoader作为父类加载器,extensionClassLoader作为插件的类加载器,
loadClass方法里面,先用systemClassLoader加载,应该是加载不到插件的Extension的,那么接下来就使用extensionClassLoader来加载,这个时候extensionClassLoader与插件的Extension是同一Context,理所当然能够加载到,但是问题是Extension extends AbstractExtension,它肯定是加载不到AbstractExtension,导致插件的Extension也加载失败
这个问题困扰了我多日了,希望哪位给个意见,帮助分析一下,我应该怎么做?
我需要在主应用中显示一个插件列表,点击某一个插件后,不是跳到插件的应用上去,而是显示为一个Dialog,在这个Dialog上有一些功能,可以对主应用产生影响,比如我的主应用上有个WebView,我做一个插件用来对主应用上的WebView进行操作,
并且我要实现的是,在主程序代码不变动的情况下,增加插件;
大家应该都知道海豚浏览器吧,他的插件原理就是这个,我现在就卡在这里了