EP10-多Service

0x00 为什么JDRobilePlugin要提供多个PluginService

昨天有个疑问,不同于PluginActivity,插件框架中是要提供多个不同的PluginService的,为什么?昨天我考虑可能是如果再次new 同一个Service木偶的时候,ClassLoader发现parent已经加载过这个类了,就会返回同一个Service实例。其实不是的。在PluginImpActivity(Activityable的子类)中提供了startActivity和startActivityForResult方法,这两个方法都会调用PluginActivity的startPluginContext()方法,而startPluginContext()会再启动一个PluginActivity的对象:

intent.setClassName(this, this.getClass().getCanonicalName());

Activity是可以存在多个自身的实例的,所以在Plugin.java中可以用startActivity方法。从前我不知道一个插件中是可以有多个木偶Activity的。。因为股神中确实只有一个木偶Activity,维护了一个巨大的UIData,其他页面都是Fragment。

虽然Service也是继承自Context的,但是一个Service在Manifest中注册之后永远只对应一个对象。它没有Activity那样的栈。如果多个木偶Service对应一个PluginService,那么生命周期就错乱了。

0x01 Serviceable和PluginImpService

现在插件中Plugin先是继承了PluginImpActivity的,PluginImlActivity继承了Activityable。PluginImpActivity在Activityable基础上丰富了一些方法比如setContentView,startActivity,getFunctionProvider等等。
同举说Serviceable可以直接去掉了,用抽象类PluginImpService直接继承Service就行了,这样就直接有了Service中所有的方法,包括生命周期。

0x02 维护多个Service

这样实现:

/**
 * 通过service木偶换取pluginService代理
 * @param clazz service木偶
 * @return pluginService代理
 */
private static Class getProxyServiceClass(Class clazz) {
    Class proxyServiceClass = null;
    //判断clazz与PluginImpService是否相同,或同是另一个类的超类或接口
    if (PluginImpService.class.isAssignableFrom(clazz)) {
        //获取clazz木偶对应的代理(sAttachServices中维护了一个这样的HashTable)
        proxyServiceClass = sAttachServices.get(clazz);
        //如果尚未分配代理,并且还有Idle的Service
        if (proxyServiceClass == null && sIdleProxyServices.size() > 0) {
            //就取出一个代理Service
            proxyServiceClass = sIdleProxyServices.get(0);
            //然后把Idle的代理Service去掉一个
            sIdleProxyServices.remove(0);
            //在HashTable中添加这一对木偶和代理的关联
            sAttachServices.put(clazz, proxyServiceClass);
        }
    }
    return proxyServiceClass;
}

sIdleProxyServices的个数,在PluginMaster中设置:

public static void init(Application app) {
        RunningEnvironment.init(app);
        ArrayList> mProxyServiceClasses = new ArrayList>();
        mProxyServiceClasses.add(ProxyService1.class);
        mProxyServiceClasses.add(ProxyService2.class);
        ServiceManager.setProxyServicesClass(mProxyServiceClasses);
    }

ProxyService1.java...等等代理Service,要在PluginMaster所在的aar(RobilePluginSDK)的Manifest中注册。
PluginMaster的lib中包含JDRobilePlugin.jar。App中compile RobilePluginSDK.aar。大概就是这样了。

-DEC 2ND

你可能感兴趣的:(EP10-多Service)