Service 分为两种工作状态:
1:启动状态,主要用于执行后台计算
Intent intent = new Intent(this,Service.class);
startService(intent);
Service 的启动过程是从 ContextWrapper 的startActivity 开始
由代码中可以看出 startService 调用到了 mBase.startService,
通过源码可以看出
mBase的类型为 Context
而Context 为抽象类, 通过 Context 、ContextWrapper、ContextImpl 这三个类的UML图可以看出
mBase.startService 实际上是执行 ContextImpl.startService
下面看 ContextImpl中的startService 方法
通过图中的标示 最终执行了 ActivityManagerNative.getDefault().startService(…..)方法
通过源代码中可以看出 改方法返回的是 一个 IActivityManager
而IActivityManager 的实现类是 ActivityManagerNative; 同时
可以看出 ActivityManagerService 继承与 ActivityManagerNative
由此可见 最终是执行 ActivityManagerService.startService(….) 方法
现在我们只需要 关注 ActivityManagerService.startService 方法即可
通过源码中我么可以看到 在ActivityManagerService.startService 中又调用了 mService.startServiceLocked(….)方法 而mService 是 ActivityService 对象 在ActivityService.startServiceLocked方法中 最后又调用了
改方法。在改方法内部 可以看出 内部 调用了 bringUpServiceLocked(….)方法。
在bringUpServiceLocked 改方法中 调用了 realStartServiceLocked 方法,通过改方法的名称 可以看出 这应该是真正启动service的方法。
紧接着 我们可以看一下 改方法内部是如何实现的。
我们可以看出 在改方法内部是通过 app.thread.scheduleCreateService(….)创建 Service 并调用了Service 的onCreate()方法
/**************************************补充说明 start********************************************/ 另外 在ActivityService realStartServiceLocked 方法中最后调用了 sendServiceArgsLocked(…)方法
在改方法的内部 调用了Service的其他方法 比如 onStartCommand 方法等。
/**************************************补充说明 end********************************************/
继续看Service的启动过程
在scheduleCreateService 中可以看出 在改方法中发送了一条消息 给 H
由此可见 H中接受到 CREATE_SERVICE 消息之后 回去创建 Service
可以看到 H 接受到消息 之后 是去执行了 handlerCreateService 方法
通过源码可以看出此事 service 创建成功并调用了 onCreate方法。
那么 handlerCreateService 改方法的主要作用是:
1:创建service 对象实例 2:创建Application 并调用Application的onCreate方法,当然Application 只会创建一次 3:创建ContextImpl对象并和Service的attach建立二者之间的关系
4:最后调用service.onCreate方法并将service对象 存储到ActivityThread中的一个列表中。
至此 Service 的启动状态 已经分析完成。
————————————————————————————————————————————————————
以下是Service 绑定状态 service 绑定状态,主要用于其他组件和Service的交互。 代码: Intent intent = new Intent(this,Service.class);
bindService(intent,ServiceConnection,BIND_AUTO_CREATE);
和Service 的启动过程是一样的,Service 的绑定过程也是从 ContextWrpper 开始。
最终会执行到 ContextImpl 到 bindServiceCommon 方法
而在改bindServiceCommon方法中 主要完成两件事;
以及
首先 我们现看第一件事情:
首先将客户端的ServiceConnection对象转化为 ServiceDispatcher.InnerConnection对象。
之所以不能直接使用ServiceConnection对象,这是因为服务的绑定有可能是跨进程的,因此 ServiceConnection对象必须借助Binder 才能让远程服务端回调自己的方法,而 ServiceDispatcher 的内部类InnerConnection 刚好充当来Binder 这个角色
ServiceDispatcher 的作用? 其实ServiceDispatcher 起着连接ServiceConnection和 InnerConnection的作用。
这个过程是有 LoadAPK.getServiceDispatcher方法实现的
系统会首先根据ServiceConnection 去获取ServiceDispatcher对象, 如果ServiceDispatcher 对象不存在 则会去创建一个改对象,
并将其存放到 map对象中 其中的影射关系是 key --ServiceConnection value -- ServiceDispathcher
注: 而在ServiceDispather 的内部又保存了 ServiceConnection和InnerConnection 对象。
当service 和客户端建立连接后,系统会通过InnerConnection 来调用ServiceConnection中的onServiceConnected方法,这个过程有可能是跨进程的。
当ServiceDispatcher 创建好了以后,getServiceDispatcher会返回其保存的InnerConnection对象。
紧接着 我们看第二件事情:
ContextImpl.bindServiceCommon 方法会通过 AMS 来完成Service的具体绑定
通过源码我们可以看出 ActivityManagerAService.bindService 会调用到 ActvityServiec.bindServiceLocked(…..);
而 在bindServiceLocked 中调用了 bringUpServiceLocked 方法
在bingUpServiceLocked 方法中又调用到了 realStartServiceLocked(…..) 方法
而从realStartServiceLocked方法和启动service 的过程是类似的,但是绑定service 会执行
requestServiceBindingLocked 方法,在改方法中执行 scheduleBindService 方法。
在scheduleBindService 中我们可以看出 bindService也是通过发送消息 在内部类H中实现的。
接下来 我们只需要看 handleBindService方法即可
可以看出 handleBindService 内部调用过来 publishService 方法,
注: Serviceyou一个特性,多次绑定Service时,service的onBind方法只会执行一次,除非Service 被终止。
当Service 的onBind方法执行以后,系统还需要通知客户端已经成功连接Service 而这个过程 是通过ActivityManagerService .publishService 方法 执行的。
通过源码可以看出 ActivityManagerService 将改实现交给来 ActivityService来实现。
现在我们只需要分析 ActivityService.publisheServiceLocked方法中的实现即可
在内部我们只需要分析改行代码 即可 c.conn.connected()
其中 c 的类型是ConnectionRecord c.conn的类型是 ServiceDispathcer.InnerConnection service 就是Service 的onBInd 方法 返回的Binder 对象,
下面 我们只需要看 ServiceDispathcer.InnerConnection 中的 connected 方法即可
从源码可以看出 InnerConnection的connected 方法有调用了 ServiceDispathcer的connected方法
对于 Service 绑定过程来说,ServiceDispatcher 的mActivityThread是一个Handler 其实它就是 ActivityThread中的H ,从前面ServiceDispatcher 的创建过程来说,mActivityThread 不会为null; 这样 Recoonection就可以经由H的post 方法运行在主线程中,因此 客户端ServiceConnection中的方法是在主线程被回调的。
很显然 RunConnection 的run方法也是简单地调用了ServiceDispatcher的doConnected方法,由于ServiceDis 怕他车人内部保存了客户端的ServiceConnection对象,因此可以很方便地调用ServiceConnction对象的onServiceConnected方法
客户端的onServiceConnected方法执行后,Service的绑定过程也就分析完成了。