小弟现正开发一个这样一个应用,这个应用做为主应用,只需要实现一些基本的功能就行,
如果要扩展功能的话,就通过开发一些小插件来实现实现原理是这样的:
主应用(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进行操作,并且我要实现的是,在主程序代码不变动的情况下,增加插件;大家应该都知道海豚浏览器吧,他的插件原理就是这个,我现在就卡在这里了

解决方案 »

  1.   

    可否考虑用service做中介站,用Contentprovider做纽带
      

  2.   

    为啥不用AIDL,用AIDL的话任何问题都好解决了啊
      

  3.   

    那你考虑一下Share吧,主Host和插件打包使用相同的签名,然后在Manifest.xml里面配置一下相同的SharedUserId,这样可以直接从主Host里面启动插件的Activity以及进行数据交互,同时Host和插件又可以同时作为单独的App运行,这种方式我觉得不错。