[Android讨论] 如何在两个应用之间共用一个接口?请教一个自定义ClassLoader

peirenlei 2011-11-22 05:42:48
小弟现正开发一个这样一个应用,这个应用做为主应用,只需要实现一些基本的功能就行,
如果要扩展功能的话,就通过开发一些小插件来实现

实现原理是这样的:
主应用(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进行操作,

并且我要实现的是,在主程序代码不变动的情况下,增加插件;

大家应该都知道海豚浏览器吧,他的插件原理就是这个,我现在就卡在这里了
...全文
343 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
ljj114624915 2012-03-23
  • 打赏
  • 举报
回复
你这个问题解决了没?
lingang1359 2011-11-23
  • 打赏
  • 举报
回复
那你考虑一下Share吧,主Host和插件打包使用相同的签名,然后在Manifest.xml里面配置一下相同的SharedUserId,这样可以直接从主Host里面启动插件的Activity以及进行数据交互,同时Host和插件又可以同时作为单独的App运行,这种方式我觉得不错。
peirenlei 2011-11-23
  • 打赏
  • 举报
回复
考虑过aidl,感觉太重
lingang1359 2011-11-22
  • 打赏
  • 举报
回复
为啥不用AIDL,用AIDL的话任何问题都好解决了啊
haoyizsw 2011-11-22
  • 打赏
  • 举报
回复
可否考虑用service做中介站,用Contentprovider做纽带
peirenlei 2011-11-22
  • 打赏
  • 举报
回复
没人回答么?

80,349

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧