当我们在编写咱们的应用程序的时候,有时候需要调用系统服务,做一些我们需要做的工作,比如调用输入法的服务,位置服务,Wifi服务等。
首先大家要知道,这些服务不是通过startService()的方式启动的,是操作系统在开机的时候或者在需要的时候通过另一种方式启动的,后面的博客中会讲到,也可以自行在网上查一下。 我们调用系统服务的时候试通过getSystemService(String serviceName)的方式进行获取的,这个方法的具体实现在ContextImpl中实现的。

这个方法是通用的访问接口,根据不同的服务名称返回不同的服务,这些服务都由serviceManager进行管理。 为什么使用这种方式?好处在于便于对服务统一管理,也便于应用开发者编写应用程序。下面主要讲一下ServiceManager,Service和Binder之间的关系。 ServiceManager运行在一个独立的进程中,其实ServiceManager本身也是一个Service,Framework提供了一个系统函数可以获取该Service对应的Binder引用。
从getSystemService()这个方法找起,如下


以获得AlarmManager为例 接着执行getAlarmManager();

第1020行 返回的Alarm服务的Binder引用 第1021行 返回一个AlarmManager的实现 第1022行 new一个AlarmManager管理类,就是用来管理这个Alarm服务
从1020行,进入到ServiceManger这个类里面,然后进去getService(ALARM_SERVICE)方法,代码如下
这个方法作用就是返回指定名字service的引用。 第51行 先从sCache中找一下是否存在这个service,如果存在就把这个IBinder返回给调用者(52、53行)。 sCache是一个存储Binder的map集合,如下代码:


如果是第一取Alarm 服务的时候是不存在的,那么就会调用第55行代码。先进入getIServiceManager()这个方法

可以看出,这个方法就是获得ServiceManager的一个静态方法,38行已经给了注释。 第39行ServiceManagerNative.asInterface(BinderInternal.getContextObject());就是用于获得ServiceManager的。 BinderInternal.getContextObject()用于获得ServiceManager服务的远程服务的Binder引用,继续进入到这个函数

这个是个native的函数,返回值就是一个远程IBinder对象引用,注释的大体意思是这个Binder是整个应用程序全家的系统对象,也就是说一个应用程序对应一个,他的一个实现就是ServiceManager,可以通过它获取其他的服务。
咱们回到ServiceManagerNative.asInterface()这个里面

大家看到了吗,是不是和上次讲的aidl生成的java文件很像。

这样就获得了IServiceManager,也是远程服务对象的引用。把IServiceManager对象赋值给了ServiceManger里面的 sServiceManager静态变量,然后再继续看下getService()方法,得到sServiceManager之后就会调用sServiceManager 的getService方法。
下面的代码:

如果在第一获取这个Alarm服务的时候,是没有的,没有就从系统服务里找到(如何被添加进去以后再讲)。
从上面看出,ServiceManager仅仅是远程IServiceManager服务的代理,把远程服务Binder的引用做为其一个静态变量。大家可以想象这样的好处。
到这里的时候就获得Alarm服务的远程IBinder的引用。回到ContextImpl这个类

从1021行代码开始,是为远程的IAlarmManager创建了一个远程服务Binder引用的代理AlarmManager.
对于android系统提供的Manager的理解
ServiceManager管理的所有Service都是以相应的Manager返回给客户端(调用者)的,在android的Framework中,
Manager的角色类似于经纪人,Manager所管理的对象是相应的服务,每个具体服务都会提供多个服务接口,Manager就是管理这个服务提供的接口 的。客户端不能直接通过Binder的引用访问具体的服务,Manager类是对客户端可见的,而远程的服务客户端是不可见的。并且每个Manager类中都有一个远程服务的Binder的引用,一般是通过构造函数传过去的,如AlarmManager:

也就是说,客户端通过Manager这个经纪人调用远程服务的引用,而间接的访问远程服务。
调用图


这种设计方式的好处是,屏蔽了对远程访问的直接访问,应用程序去调用服务的时候会更加灵活,对于系统设计来说,对于api的设计也可控的,只让客户端访问允许访问的功能(电话拦截,挂断电话就可以屏蔽掉,如果您理解了这两篇帖子的话,对于这样的功能实现也就小kiss了)。
ok,先写到这里,如有错误,敬请指正。

更多相关文章

  1. Android官方文档—APP组件(Services)(AIDL)
  2. android中图片的三级cache策略(内存、文件、网络)之二:内存缓存策略
  3. Android五分钟轻松教会你掌握WebView与js交互
  4. 如何在 Android(安卓)Studio 中引用不在项目文件夹中的 jar
  5. Android(安卓)Studio导入指定的jar包
  6. android下使用htop和lsof
  7. 关于webview最详细讲解(包含 h5 和android 交互)
  8. Android(安卓)Service startForeground() 可能不显示Notificatio
  9. Android之Http协议编程02

随机推荐

  1. Android(安卓)快速掌握Activity生命周期
  2. 关于Studio和EclipseSHA1值的查看
  3. android 只定义下边边框
  4. Android数据通信开发与应用(四):实战开发
  5. 使用泛型方法在Java中安全地进行强制类型
  6. Android使用intent跳转到其它应用activit
  7. Android开发指南(32) —— Multimedia an
  8. 【翻译】Android(安卓)Support Library
  9. [Android]使用RecyclerView替代ListView(
  10. Android(安卓)平台下使用 i2c-tools