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<? extends Service> getProxyServiceClass(Class<?> clazz) {
    Class<? extends PluginService> 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<Class<? extends PluginService>> mProxyServiceClasses = new ArrayList<Class<? extends PluginService>>();
        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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容