Architecture of I19tSDK AIDLs

根据图示的内容,整个I19tSDK的部分分为两大块,即Server端和Client端
Server端
跟所有的AIDL调用一样,Server端是以AIDL Stub为基础的。从UML class图的关系图可以看到,Stub的汇聚点是BinderProvider:
- 继承自Android
ContentProvider - addService到
ServiceCache,建立与RegionRecognizerService的依赖关系 - 持有
ServiceFetcher对象,该对象为IServiceFetcher.Stub子类实例
Client端
通过ServiceManagerNative创建了Client端的服务获取中台:
- 通过
ProviderCaller和Server端的BinderProvider发生联系 - 持有
IServiceFetch,通过ServiceFetch查询到Server端的ServiceCache,获取远端Service - 通过getService方法,获取到
IRegionRecognizer的client实例
时序图
从整个运行的过程来看,分为两大部分:
- 第一部分是Server & Client初始化。
- 第二部分是通过Client端的Proxy Service获取Server端Service的具体能力。
初始化
如下图所示:
- 整个流程的发起方式
I19tCore调用startup,通过startup会调用到ServiceManagerNative中 - 在
ServiceManagerNative的startup中,会直接调用ProviderCaller的call函数,其中传入的参数为:MethodConstants.INIT_SERVICE,意思是本次调用会初始化操作。 - 由于
ProviderCaller实际是一个ContentResolver的wrapper,因此就通过authority查找到了对应注册在AndroidManifest中的ContentProvider,即BinderProvider:private static final String SERVICE_CP_AUTH = “com.blackshark.i19tsdk.syncprovider”;
- 由于
ContentProvider的call是一个同步调用,因此Client端会阻塞,进入到Server端继续进行下一步逻辑的处理,而由于此时ContentProvider并没有运行,因此会先调用onCreate函数进行初始化操作 - 在
BinderProvider的onCreate中,我们主要完成了Remote Service的初始化,即XXXService.systemReady,以及添加Service到本地的ServiceCache中 - 在完成
onCreate函数后,由Android ContentProvider的机制所限定,会继续跑到call函数,根据我们传入的arg:MethodConstants.INIT_SERVICE,我们直接做bypass,不予处理即可。 - 至此,整个从Client端发起的
startup流程就走完了,从Server端一路返回到Client,放开阻塞后Client代码继续运行。
通过借用ContentProvider的arg参数,完成了同步初始化Server端运行环境的业务,避免了使用AIDL Service异步start的问题,避免了使用回调函数监听onBinder的问题。
一个业务逻辑
Client端的recognize识别,如下图所示:
需要注意的是,以上的流程是已经在经历了第一部分初始化业务之后了。
- 外部App需要发起一次识别操作,首先需要初始化对应的Recognizer。
- 通过
RegionRecognizer.getInstance获取RegionRecongizer实例 - 由于是第一次在Client端初始化RegionRecognizer,因此会尝试与远端服务建立联系,这里就需要通过
ServiceManagerNative来做桥梁 - 仿照第一部分初始化的流程,这里借用
ProviderCaller来进行同步IPC动作,旨在获取ServiceFetcher的Proxy代理对象mServiceFetcher,该对象通过Bundle传回 - 通过
ServiceFetcher对象获取到远程XXXXService的Binder实例 - 通过
XXXXX.Stub.asInterfaces把Binder实例转化为本地的Proxy对象 - 在做具体业务
recognize时,通过上面获取到的Proxy对象,调用到远程的实际Service完成对应的业务。
以上两个步骤,也是借用了Android ServiceManager的逻辑,通过在Client端建立一个Service大管家,保存各个Service的Proxy实例,使得Client端在每次使用具体Service时不用都去跑一遍IPC,以达到简化流程的目的。同时,通过ServiceFetcher对象,建立了Client端与Server端的服务映射关系。