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