Service 工作流程

Service 分为两种工作状态:
1:启动状态,主要用于执行后台计算

Intent intent = new Intent(this,Service.class);
startService(intent);

Service 的启动过程是从 ContextWrapper 的startActivity 开始
《Service 工作流程》

由代码中可以看出 startService 调用到了 mBase.startService,

通过源码可以看出

《Service 工作流程》

mBase的类型为 Context

《Service 工作流程》

而Context 为抽象类, 通过 Context 、ContextWrapper、ContextImpl 这三个类的UML图可以看出

《Service 工作流程》

mBase.startService 实际上是执行 ContextImpl.startService

下面看 ContextImpl中的startService 方法

《Service 工作流程》

通过图中的标示 最终执行了 ActivityManagerNative.getDefault().startService(…..)方法
《Service 工作流程》

通过源代码中可以看出 改方法返回的是 一个 IActivityManager

而IActivityManager 的实现类是 ActivityManagerNative; 同时

《Service 工作流程》

可以看出 ActivityManagerService 继承与 ActivityManagerNative

由此可见 最终是执行 ActivityManagerService.startService(….) 方法

现在我们只需要 关注 ActivityManagerService.startService 方法即可

《Service 工作流程》

通过源码中我么可以看到 在ActivityManagerService.startService 中又调用了 mService.startServiceLocked(….)方法 而mService 是 ActivityService 对象 在ActivityService.startServiceLocked方法中 最后又调用了

《Service 工作流程》

改方法。在改方法内部 可以看出 内部 调用了 bringUpServiceLocked(….)方法。

《Service 工作流程》

在bringUpServiceLocked 改方法中 调用了 realStartServiceLocked 方法,通过改方法的名称 可以看出 这应该是真正启动service的方法。

《Service 工作流程》
紧接着 我们可以看一下 改方法内部是如何实现的。

《Service 工作流程》

我们可以看出 在改方法内部是通过 app.thread.scheduleCreateService(….)创建 Service 并调用了Service 的onCreate()方法
/**************************************补充说明 start********************************************/ 另外 在ActivityService realStartServiceLocked 方法中最后调用了 sendServiceArgsLocked(…)方法

《Service 工作流程》

在改方法的内部 调用了Service的其他方法 比如 onStartCommand 方法等。

/**************************************补充说明 end********************************************/

继续看Service的启动过程

《Service 工作流程》

在scheduleCreateService 中可以看出 在改方法中发送了一条消息 给 H

由此可见 H中接受到 CREATE_SERVICE 消息之后 回去创建 Service

《Service 工作流程》

可以看到 H 接受到消息 之后 是去执行了 handlerCreateService 方法
《Service 工作流程》

通过源码可以看出此事 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 开始。

《Service 工作流程》

最终会执行到 ContextImpl 到 bindServiceCommon 方法
而在改bindServiceCommon方法中 主要完成两件事;

《Service 工作流程》

以及

《Service 工作流程》

首先 我们现看第一件事情:

首先将客户端的ServiceConnection对象转化为 ServiceDispatcher.InnerConnection对象。

之所以不能直接使用ServiceConnection对象,这是因为服务的绑定有可能是跨进程的,因此 ServiceConnection对象必须借助Binder 才能让远程服务端回调自己的方法,而 ServiceDispatcher 的内部类InnerConnection 刚好充当来Binder 这个角色

ServiceDispatcher 的作用? 其实ServiceDispatcher 起着连接ServiceConnection和 InnerConnection的作用。

这个过程是有 LoadAPK.getServiceDispatcher方法实现的

《Service 工作流程》

系统会首先根据ServiceConnection 去获取ServiceDispatcher对象, 如果ServiceDispatcher 对象不存在 则会去创建一个改对象,
并将其存放到 map对象中 其中的影射关系是 key --ServiceConnection value -- ServiceDispathcher

注: 而在ServiceDispather 的内部又保存了 ServiceConnection和InnerConnection 对象。

当service 和客户端建立连接后,系统会通过InnerConnection 来调用ServiceConnection中的onServiceConnected方法,这个过程有可能是跨进程的。
当ServiceDispatcher 创建好了以后,getServiceDispatcher会返回其保存的InnerConnection对象。

紧接着 我们看第二件事情:

ContextImpl.bindServiceCommon 方法会通过 AMS 来完成Service的具体绑定

《Service 工作流程》

通过源码我们可以看出 ActivityManagerAService.bindService 会调用到 ActvityServiec.bindServiceLocked(…..);

《Service 工作流程》
而 在bindServiceLocked 中调用了 bringUpServiceLocked 方法

《Service 工作流程》

在bingUpServiceLocked 方法中又调用到了 realStartServiceLocked(…..) 方法

而从realStartServiceLocked方法和启动service 的过程是类似的,但是绑定service 会执行
《Service 工作流程》

requestServiceBindingLocked 方法,在改方法中执行 scheduleBindService 方法。

《Service 工作流程》

在scheduleBindService 中我们可以看出 bindService也是通过发送消息 在内部类H中实现的。

《Service 工作流程》

接下来 我们只需要看 handleBindService方法即可

《Service 工作流程》

可以看出 handleBindService 内部调用过来 publishService 方法,

注: Serviceyou一个特性,多次绑定Service时,service的onBind方法只会执行一次,除非Service 被终止。

当Service 的onBind方法执行以后,系统还需要通知客户端已经成功连接Service 而这个过程 是通过ActivityManagerService .publishService 方法 执行的。

《Service 工作流程》

通过源码可以看出 ActivityManagerService 将改实现交给来 ActivityService来实现。

现在我们只需要分析 ActivityService.publisheServiceLocked方法中的实现即可

《Service 工作流程》

在内部我们只需要分析改行代码 即可 c.conn.connected()

其中 c 的类型是ConnectionRecord c.conn的类型是 ServiceDispathcer.InnerConnection service 就是Service 的onBInd 方法 返回的Binder 对象,

下面 我们只需要看 ServiceDispathcer.InnerConnection 中的 connected 方法即可
《Service 工作流程》

从源码可以看出 InnerConnection的connected 方法有调用了 ServiceDispathcer的connected方法
《Service 工作流程》

对于 Service 绑定过程来说,ServiceDispatcher 的mActivityThread是一个Handler 其实它就是 ActivityThread中的H ,从前面ServiceDispatcher 的创建过程来说,mActivityThread 不会为null; 这样 Recoonection就可以经由H的post 方法运行在主线程中,因此 客户端ServiceConnection中的方法是在主线程被回调的。

《Service 工作流程》

很显然 RunConnection 的run方法也是简单地调用了ServiceDispatcher的doConnected方法,由于ServiceDis 怕他车人内部保存了客户端的ServiceConnection对象,因此可以很方便地调用ServiceConnction对象的onServiceConnected方法
《Service 工作流程》

客户端的onServiceConnected方法执行后,Service的绑定过程也就分析完成了。

    原文作者:ActivityManagerService
    原文地址: https://juejin.im/entry/581d9e5cda2f60005df7674c
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞