Android 四大组件之 Service Record

一. 引言

Android系统中最为重要的服务便是AMS, AMS管理着framework层面四大组件和进程. 本文从另一个维度来说一说四大组件之一的Service. 每个app进程运行的Service, 对应于system_server进程中AMS的ServiceRecord对象.也就是说所有app进程的Service, 都会记录在system_server进程, 好比一个大管家.

本文的重点是讲解AMS如何管理Service.

二. Service数据结构

先以一幅图来展示AMS管理Service所涉及的相关数据结构:
点击查看大图

图中,从上至下存在简单的包含关系:

  • ServiceRecord可以包含一个或多个IntentBindRecord;
  • IntentBindRecord可以包含一个或多个AppBindRecord;
  • AppBindRecord可以包含一个或多个ConnectionRecord;

2.1 ServiceRecord

ServiceRecord位于system_server进程,是AMS管理各个app中service的基本单位。
ServiceRecord继承于Binder对象,作为Binder IPC的Bn端;Binder将其传递到Service进程的Bp端,保存在Service.mToken, 即ServiceRecord的代理对象。

ServiceRecord的成员变量app,用于记录当前service运行在哪个进程。再来说说其他成员变量:

(1)bindings:由于可通过不同的Intent来bind同一个service,故采用bindings来记录所有的intent以及对应的IntentBindRecord,其数据类型如下:

    ArrayMap<Intent.FilterComparison, IntentBindRecord> bindings

(2)connections:记录IServiceConnection以及所有对应client的ConnectionRecord

(3)startRequested:代表service是否由startService方式所启动的

  • startService(),则startRequested=true;
  • stopService()或stopSelf(),则startRequested=false;

2.2 IntentBindRecord

功能: 一个绑定的Intent与其对应的service

(1)apps: 由于同一个intent,可能有多个不同的进程来bind该service,故采用其成员变量aPps来记录该intent绑定的所有client进程,
其数据类型如下:

    ArrayMap<ProcessRecord, AppBindRecord> apps

(2)binder: service发布过程,调用publishServiceLocked()来赋值的IBinder对象;也就是bindService后的onBinder()方法的返回值(作target进程的binder服务)的代理对象。简单来说就是onServiceConnected()的第二个参数。

(3)received:

  • 当执行完publishServiceLocked(), 则received=true; requested=true;
  • 当执行killServicesLocked(), 则received=false; requested=false;

2.3 AppBindRecord

功能:一个service与其所关联的client进程其成员变量connections记录所有的连接信息;

2.4 ConnectionRecord

功能:记录一个service的绑定信息binding; 只有bindService()才会创建该对象。

  1. conn:client进程中的LoadedApk.ServiceDispatcher.InnerConnection的Bp端
  2. activity:不为空,代表发起方拥有activity上下文
  3. clientIntent: 记录如何启动client

执行bindService()便会创建ConnectionRecord对象, 该对象创建后添加到以下对象的列表:

  • ServiceRecord.connections: 记录在ServiceRecord的成员变量;
  • ActiveServices.mServiceConnections: 效果同上;
  • AppBindRecord.connections: 某个service的所有绑定信息会记录在该对象;
  • ProcessRecord.connections: 记录在service所对应的client进程
  • ActivityRecord.connections: 当bindService()过程是由activity context所启动, 则会添加到该对表;否则跳过;

当bindService过程中指定参数flags Context.BIND_AUTO_CREATE, 则会在bind过程创建service;

2.5 LoadedApk

LoadedApk对象,往往运行在client进程,通过其成员变量mServices来记录相关的service信息。不同的Context下,对于同一个ServiceConnection会对应唯一的LoadedApk.ServiceDispatcher对象。ServiceDispatcher用于服务分发,即服务连接或死亡事件的派发。

bindService过程并不是直接把ServiceConnection(只是Interface)传递到AMS,而是创建一个InnerConnection(Binder对象)再传递到AMS,这样便于跨进程间交互。

三. Service综述

3.1 启动与销毁

对Service的主要操作如下四个方法:

    startService(Intent service)
    stopService(Intent service)
    bindService(Intent service, ServiceConnection conn, int flags)
    unbindService(ServiceConnection conn)

其中:
```java

top Created with Sketch.