1.Binder Service端只要基于Binder类新建一个Server类重新Binder的onTransace()即可,这种方式是用来扩展系统服务,而对于客户端服务则必须基于四大组件的Service类来编写。所谓的系统服务是指可以使用getSystemService()方法获取的服务,所谓的客户端服务是指应用程序提供的自定义服务。
2.AMS提供了bindService(Intent service, ServiceConnection conn, int flags)函数来绑定一个服务,其原型在android.app.ContextImpl类中。当客户都请求AMS启动一个Service以后,Ams就会远程调用ActivityThread类中的ApplicationThread对象,调用的参数包含Service的Binder引用,然后在ApplicationThread中回调bindService中的conn接口。因此客户端可以在onServiceConnected()方法中得到服务的Binder引用,然后通过asInterface(Binder引用) 返回服务代理 来操作服务。
3.在应用程序中经常使用getSystemService(String serviceName)方法回去一个系统服务,该方法的实现是在ContextImpl类中,该方法返回的Service比较多,一般都是由ServiceManager管理。ServiceManager不直接将这些服务返回给客户都,而是将Service对应的Manager返回给客户端, 这个Manager类似Service的一个代理,客户端通过Manager间接的和Service打交道(如ActivityManagerService由ActiviyManager来间接操作)。
4.AIDL(Android Interface Description Language)的简写,是用于客户端/服务端通信接口的一种描述语言。我们自己编写服务需要提供一个接口,而且客户端和服务端必须统一实现这个接口。客户端和服务端与Binder驱动交互还用到Parcel的读写数据,外界还要得到Server服务,这些都是需要手工来书写,现在AIDL就是用来简化实现BinderServer的。
5.AIDL文件以.aidl后缀,就是客户端/服务端需要统一实现的服务接口,里面包含具体业务的方法。以androidStudio为例,需要在main目录下创建一个aidl文件夹,和java同一层级。当使用AS右键新建AIDL文件时 AS自动帮我们创建。如果需要用到自定义的类,还需要创建 类名.aidl 且必须和该类在同一包下。目录结构如下
6.由于gradle默认会在java目录下找依赖的类,所以会提示找不到Student类,需要在module下的build.gradle改一下默认行为,在android下添加如下:
7.由于5.0以后隐式声明Intent 启动Service变化,通过源码发现 隐式启动只要保证Component或者package其一不为空即可: