从AIDL的角度来看Binder的实现过程,结合浅析(一)和Activity启动流程的讲解来分析。
分析
1 | public interface MusicAIDLService extends android.os.IInterface { |
省略了内部类Stub和Proxy的很多实现,先来梳理一下大致的逻辑框架。
- 接口MusicAIDLService,定义了我们在aidl中声明的远程服务方法(play、pause..),并且继承自IInterface
- Stub类继承自Binder,实现上面的MusicAIDLService接口,重写了传输方法onTransact
- Proxy类实现了MusicAIDLService接口,持有IBinder实例mRemote,重写了MusicAIDLService中定义的远程服务方法(play、pause..)
那么我们是怎么使用这些来完成一次跨进程的通信呢
1 | private MusicAIDLService mMusicServiceProxy ; |
在onServiceConnected时,通过Stub.asInterface,其实返回的是上述的Proxy类实例,我们通过这个mMusicServiceProxy
的方法,来调用到远程的服务,如mMusicServiceProxy.play();
1 |
|
通过mRemote.transact来传输_data。此时的mRemote就是上面MusicAIDLService.Stub.asInterface(service)
的service,也就是onServiceConnected方法的第二个参数,即我们通过intent绑定的Service(运行在另一个进程的)的onBind方法的返回值。
由此引入第四个角色,真正的远程服务实现类mServiceBinder
。
1 |
|
OK,流程就这样。我把上面总结的重新贴一下:
- MusicAIDLService 接口,定义了我们在aidl中声明的远程服务方法(play、pause等),并且继承自IInterface
- Stub 抽象类,继承自Binder,实现上面的MusicAIDLService接口但没有重写远程服务方法,重写了传输方法
onTransact
,在跨进程时asInterface
方法返回内部类Stub.Proxy(obj)
实例 - Proxy 实现了MusicAIDLService接口,持有IBinder实例mRemote,重写了MusicAIDLService中定义的远程服务方法(play、pause等),在其中调用
mRemote.transact()
来进行数据传输 - mServiceBinder 真正的远程音乐服务,业务逻辑实现。继承了Stub,重写了远程服务方法(play、pause等)。
再回过头分析一下ActivityManagerService、ActivityManagerNative、IActivityManager、ActivityManagerProxy四个兄弟。
- IActivityManager 接口,定义了Activity远程服务的方法(startActivity等),并且继承自IInterface
- ActivityManagerNative 抽象类,继承自Binder,实现上面的IActivityManager接口但没有重写远程服务方法,重写了传输方法
onTransact
,asInterface
返回ActivityManagerProxy(obj)
实例 - ActivityManagerProxy 实现了IActivityManager接口,持有IBinder实例mRemote,重写了IActivityManager中定义的远程服务方法(startActivity等),在其中调用
mRemote.transact()
来进行数据传输 - ActivityManagerService 真正的远程Activity管理服务类,继承了ActivityManagerNative,重写了远程服务的方法(startActivity等)
关系很明了,无需多言了!