架构感觉不是一个体系,或者说每一种架构都是一个体系,各有优势和使用场景,不是一脉相承的,暂时先放在博客中。
TODO:结合架构案例,多画图,提供Demo
TvApi设计
- 定义AIDL接口
- 封装Binder调用:
- Binder连接池:
- Service端有几百个方法,拆成了几十个业务接口,每个都开一个Service消耗较大
- 通过一个Service,实现ITvApiManager接口,调用
getTVApiSystemInputSource()
返回不同的IBinder对象 - IBinder对象保存在Map中
<Class, <ApiElement>>
:mwApi.registerFunction(TVApiSoundImpl.class);
内部通过反射实例化对象,并创建对应的动态代理对象,包含在ApiElement中。
- 动态代理+反射发notify:
- 客户端创建IBinder监听器(回调参数onTvNotify("action", "bundle")),通过AIDL传给服务端IBinder对象,服务端保存监听器列表
- 接口的notify方法使用
@NotifyAction("name")
注解,参数使用@NotifyParams("key1")
注解 - 接口实现类空实现:避免每个notify方法都封装一遍参数到Bundle中,再手动遍历监听器列表通知
- 调用空方法时,会通过动态代理类invoke调用
- 动态代理类中判断如果使用了注解,遍历读取参数,存入Bundle中,遍历通知客户端的IBinder监听器
Client端调用SDK方法,Service端实现接口
Executive
:
- 添加注解,生成工厂类,create实例化Executive,并且解析皮肤配置的Executive参数。
- registerAll的时候将所有Executive工厂放到池中
Map<String, IExecutiveCreator>
- bindView的时候,解析皮肤配置的ComponentInfo参数,获取Executive字符串
- 根据Executive字符串获取对应的工厂,调用create方法实例化Executive,并放入弱引用Map中
Map<PageData.ComponentInfo, WeakReference<IExecutive>>
,下次同一个控件获取不需要再实例化
KeyHandler:责任链
- 系统在
PhoneWindowManager
中方法中添加拦截interceptKeyBeforeDispatching
,将Key传给TvAPI - TvAPI提供了addListener监听方法
- 其他应用调用addListener方法,注册监听
- 按键分发时遍历监听器,分发给不同应用处理,例如GlobalUI,音量条