Service 概述

Service 特点
Service 也是 AMS 所管理的对象
Service 可以单独启动，而不用跟随 Activity 一起启动 （但同样要启动该 Service 所属的进程，也就是 ActivityThread）
AMS 会通知 ActivityThread 来启动 Service
一般 App 启动 Service 有两种方式
通过 Context#startService 来启动指定 Service
通过 Context#bindService 绑定 Service

绑定 Service

Copy
public class TestService extends AppCompatActivity {
// 匿名类
private ServiceConnection serviceConnection = new ServiceConnection() {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

Intent intent = new Intent(this, MyService.class);
bindService(intent, serviceConnection, BIND_AUTO_CREATE);
}

@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
// 向下转型（当然你也可以用Binder提供的方法）
MyService.MyBindClass bindClass = (MyService.MyBindClass) iBinder;
}

@Override
public void onServiceDisconnected(ComponentName componentName) {
}
};
}

ContextImpl - bindService 调用 AMS 注册 Receiver

Context 的实作类是 ContextImpl类 （原因可以看看 Activity#attach 函数，这里就不细讲），所以在使用 bindService 的时候，实作类就是 ContextImpl
取得 IServiceConnection 对象：透过 LoadApk#getServiceDispatcher取得 IServiceConnection 对象，IServiceConnection 是 APP 端 IBinder Server 对象，将来让 AMS 做回调用 （下个小节说明）
取得 Binder Proxy 访问 AMS:ActivityManager#getService取得 Binder 代理类，透过代理类呼叫AMS#bindIsolatedService 方法

Copy
// ContextImpl.java

final @NonNull LoadedApk mPackageInfo;

@Override
public boolean bindService(Intent service, ServiceConnection conn, int flags) {
...

return bindServiceCommon(service, conn, flags, null, mMainThread.getHandler(), null,
getUser());
}

private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags,
String instanceName, Handler handler, Executor executor, UserHandle user) {

IServiceConnection sd;

// 判空
if (conn == null) {
throw new IllegalArgumentException("connection is null");
}
if (handler != null && executor != null) {
throw new IllegalArgumentException("Handler and Executor both supplied");
}

// mPackageInfo 类型 LoadedApk
if (mPackageInfo != null) {

// @ 1. 主要是要透过 LoadedApk#getServiceDispatcher，包裝出 IServiceConnection
if (executor != null) {
sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), executor, flags);
} else {
sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
}
} else {
throw new RuntimeException("Not supported in system context");
}

validateServiceIntent(service);
try {

... 省略部分

// @ 2. 分析 AMS#bindIsolatedService 方法
int res = ActivityManager.getService().bindIsolatedService(
mMainThread.getApplicationThread(), getActivityToken(), service,
service.resolveTypeIfNeeded(getContentResolver()),
sd, flags, instanceName, getOpPackageName(), user.getIdentifier());

// 绑定结果
if (res < 0) {
throw new SecurityException(
"Not allowed to bind to service " + service);
}
return res != 0;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}

IServiceConnection 创建 Binder 回调 - Service 连线

分析 LoadedApk#getServiceDispatcherCommon 方法：可以发现它主要在创建 IServiceConnection 接口，该接口之后会让 AMS 做回调
检查 Cache：首先检查本地缓存是否有该 Service 的 Binder 回调（Context 作为 Key），如果有的话直接返回，否则创建 ServiceDispatcher 对象
如果没有就创建 LoadedApk.ServiceDispatcher 对象
透过 getIServiceConnection 取得 Binder Server 回调接口

Copy
// LoadedApk.java

public final class LoadedApk {

// ServiceDispatcher 的缓存
private final ArrayMap<Context, ArrayMap<ServiceConnection,
LoadedApk.ServiceDispatcher>> mServices = new ArrayMap<>();

public final IServiceConnection getServiceDispatcher(ServiceConnection c,
Context context, Handler handler, int flags) {
// @ 追踪 getServiceDispatcherCommon
return getServiceDispatcherCommon(c, context, handler, null, flags);
}

private IServiceConnection getServiceDispatcherCommon(ServiceConnection c,
Context context, Handler handler, Executor executor, int flags) {

synchronized (mServices) {
LoadedApk.ServiceDispatcher sd = null;
ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map =
mServices.get(context);

// 1. 判断缓存
if (map != null) {
...

sd = map.get(c); // 有缓存
}

if (sd == null) {
// @ 2. 没缓存，直接创建 (根据回传的接口进行创建)
if (executor != null) {
sd = new ServiceDispatcher(c, context, executor, flags);
} else {
sd = new ServiceDispatcher(c, context, handler, flags);
}

...

if (map == null) {
map = new ArrayMap<>();
mServices.put(context, map);
}
map.put(c, sd);
} else {
sd.validate(context, handler, executor);
}

// 3. 分析 LoadedApk.ServiceDispatcher#getIServiceConnection
return sd.getIServiceConnection();
}

}
}

ServiceDispatcher 类：是 LoadedApk 的静态内部类，真正给 AMS 回调的 Binder 是 InnerConnection 类，当 AMS 回调时会呼叫 connected 方法
创建 IServiceConnection.Stub 给 AMS 回调
AMS 回调实，会创建 RunConnection 对象，让 Handler or Executor 呼叫
App 端 IServiceConnection 服务实作，类关系图

Copy
// LoadedApk.java

public final class LoadedApk {

static final class ServiceDispatcher {

private final ServiceDispatcher.InnerConnection mIServiceConnection;

private static class InnerConnection extends IServiceConnection.Stub {

// 弱引用
final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;

InnerConnection(LoadedApk.ServiceDispatcher sd) {
mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);
}

// AMS 在呼叫时会使用 connected 方法
public void connected(ComponentName name, IBinder service, boolean dead)
throws RemoteException {
LoadedApk.ServiceDispatcher sd = mDispatcher.get();
if (sd != null) {
// @ 分析 connected
sd.connected(name, service, dead);
}
}
}

// 建构式
ServiceDispatcher(ServiceConnection conn,
Context context, Handler activityThread, int flags) {

// 创建 InnerConnection 对象
mIServiceConnection = new InnerConnection(this);

... 省略部分參數

}

IServiceConnection getIServiceConnection() {
// 实现类实作 IServiceConnection.Stub
return mIServiceConnection;
}

public void connected(ComponentName name, IBinder service, boolean dead) {
// 如果有设定Executor就通过Executor通知
if (mActivityExecutor != null) {
// 通过 Executor
mActivityExecutor.execute(new RunConnection(name, service, 0, dead));
} else if (mActivityThread != null) {
// @ 透过 Handler (ActivityThread#H 类)
mActivityThread.post(new RunConnection(name, service, 0, dead));
} else {
doConnected(name, service, dead);
}
}

}
}

AMS 透过 Binder 回调 - ServiceConnection

RunConnection 类：是一个 Runnable，以目前状况来说是使用 Handler，这个 Runnable 会传到ActivityThread#H类（也是个 Handler）让它回调

Copy
// LoadedApk#ServiceDispatcher#RunConnection.java

private final class RunConnection implements Runnable {

// 构建
RunConnection(ComponentName name, IBinder service, int command, boolean dead) {
mName = name;
mService = service;
mCommand = command;
mDead = dead;
}

public void run() {
// 目前传入的 mCommand = 0
if (mCommand == 0) {
// @ 分析 doConnected 方法
doConnected(mName, mService, mDead);
} else if (mCommand == 1) {
doDeath(mName, mService);
}
}

final ComponentName mName;
final IBinder mService;
final int mCommand;
final boolean mDead;
}

ServiceDispatcher#doConnected 方法：对 App 传入的 ServiceConnection 接口进行回调，并有多个状况如下

是否同名 Server cache | 目标 IBinder 状态 | 说明 | 处理行为
Y | 比对相同 | 已连线 | 直接返回，不多作处理
Y | 比对不相同 | 已连线，但取得不同 IBinder 代理 | 1. 先断线 onServiceDisconnected，2. 再次连线 onServiceConnected
N | IBinder 不为空 | 第一次连线 | 连线呼叫 onServiceConnected

Copy
// LoadedApk#ServiceDispatcher.java

private final ServiceConnection mConnection;

public void doConnected(ComponentName name, IBinder service, boolean dead) {
ServiceDispatcher.ConnectionInfo old;
ServiceDispatcher.ConnectionInfo info;

synchronized (this) {
...

old = mActiveConnections.get(name);
// 1. 判断是否已经绑定&&是同一个Binder
if (old != null && old.binder == service) {
// Huh, already have this one. Oh well!
return;
}

if (service != null) {
// 开始联机新Service
info = new ConnectionInfo();
info.binder = service;
info.deathMonitor = new DeathMonitor(name, service);
try {
service.linkToDeath(info.deathMonitor, 0);
mActiveConnections.put(name, info);
} catch (RemoteException e) {
// This service was dead before we got it... just
// don't do anything with it.
mActiveConnections.remove(name);
return;
}
} else {
// Service disconnect 从缓存中移除
mActiveConnections.remove(name);
}

if (old != null) {
old.binder.unlinkToDeath(old.deathMonitor, 0);
}
}
// 2. 如果是旧连接，呼叫onServiceDisconnected断开但不同IBinder
if (old != null) {
mConnection.onServiceDisconnected(name);
}

if (dead) {
mConnection.onBindingDied(name);
} else {
// If there is a new viable service, it is now connected.
if (service != null) {

// 3. 呼叫 onServiceConnected (回到使用者接口)
mConnection.onServiceConnected(name, service);
} else {
mConnection.onNullBinding(name);
}
}
}

AMS - 启动、绑定 Service 过程

客户端 APP 透过ContextImpl#bindService，来触发AMS#bindIsolatedService方法，绑定 APP & Service
检查 Service Intent 必须要有 FileDescriptors
呼叫 ActiveServices#bindServiceLocked 方法

Copy
// ActivityManagerService.java

// 存活的 Servcie 列表
final ActiveServices mServices;

public int bindIsolatedService(IApplicationThread caller, IBinder token, Intent service,
String resolvedType, IServiceConnection connection, int flags, String instanceName,
String callingPackage, int userId) throws TransactionTooLargeException {
enforceNotIsolatedCaller("bindService");

// 1. 检查 intent
// intent 必须要有 FileDescriptors
if (service != null && service.hasFileDescriptors() == true) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}

// 检查客戶端包名
if (callingPackage == null) {
throw new IllegalArgumentException("callingPackage cannot be null");
}

... 省略部分

// 函数取名中有 Lock 的原因，对呼叫线程堵塞
synchronized(this) {

// @ 2. 呼叫 ActiveServices#bindServiceLocked
return mServices.bindServiceLocked(caller, token, service,
resolvedType, connection, flags, instanceName, callingPackage, userId);
}

}

ActiveServices#bindServiceLocked 方法
检查呼叫者进程是否存在（可能已被 kill），若不存在则抛出
透过 retrieveServiceLocked 方法:去 PKMS 中找到对应的 Service 信息
App 端设定的 BIND_AUTO_CREATE Flag 若有设置该 Flag，就会透过 bringUpServiceLocked 方法 自动创建该 Service
透過 requestServiceBindingLocked 方法：要求綁定 Service，這個函數包含了第一次綁定 & 重新綁定的功能 (差異在最後一個參數)

Copy
// ActiveServices.java

int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
String resolvedType, final IServiceConnection connection, int flags,
String instanceName, String callingPackage, final int userId)
throws TransactionTooLargeException {

// 呼叫者 Pid、Uid
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();

// 1. 透过AMS寻找呼叫者进程
final ProcessRecord callerApp = mAm.getRecordForAppLOSP(caller);

if (callerApp == null) {
// 抛出错误
throw new SecurityException(
"Unable to find app for caller " + caller
+ " (pid=" + callingPid
+ ") when binding service " + service);
}

...

//2. 搜寻PKMS中的Service
ServiceLookupResult res =
retrieveServiceLocked(service, instanceName, resolvedType, callingPackage,
callingPid, callingUid, userId, true,
callerFg, isBindExternal, allowInstant);

// 若没有res代表没有该Service
if (res == null) {
return 0;
}

// 判断其中的 ServiceRecord
if (res.record == null) {
return -1;
}

ServiceRecord s = res.record;

...

try {
...

// 自动启动 Service
if ((flags&Context.BIND_AUTO_CREATE) != 0) {
s.lastActivity = SystemClock.uptimeMillis();
needOomAdj = true;

// 自动启动 Service
if (bringUpServiceLocked(s, service.getFlags(), callerFg, false,
permissionsReviewRequired, packageFrozen, true) != null) {
mAm.updateOomAdjPendingTargetsLocked(OomAdjuster.OOM_ADJ_REASON_BIND_SERVICE);
return 0;
}
}

...

AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);

// Service 连接纪录
ConnectionRecord c = new ConnectionRecord(b, activity,
connection, flags, clientLabel, clientIntent,
callerApp.uid, callerApp.processName, callingPackage);

... 調整 OomAdj 數值

// 判斷 Service 進程是否啟動 (app 就是 ProcessReocrd)
if (s.app != null && b.intent.received) {

try {
// 透过使用者传入的接口进行进行回掉
// 上个小节有分析过（conn就是IServiceConnect），最终会呼叫到onServiceConnected
c.conn.connected(s.name, b.intent.binder, false);
} /* 省略 catch */

// 如果当前应用进程是第一个与Service进程绑定的
// &&有调用过doRebind方法
if (b.intent.apps.size() == 1 && b.intent.doRebind) {
// 最后一个参数表示，是否重新绑定
// @分析requestServiceBindingLocked方法
requestServiceBindingLocked(s, b.intent, callerFg, true);
}

} else if (!b.intent.requested) { // 应用端没有绑定过
// 最后一个参数表示，是否重新绑定
requestServiceBindingLocked(s, b.intent, callerFg, false);
}

...

} finally {
Binder.restoreCallingIdentity(origId);
}

return 1;
}

ActiveServices#requestServiceBindingLocked 方法：针对传入的 ServiceRecord 来进行判断、操作
检查 ServiceRecord 指定的进程是否起动（检查 ProcessRecord & IApplicationThread 是否存在），也就是检查 Service 是否启动
目前假设 Service 目标进程已经启动，那就会透过该进程内实现的IApplicationThread#requestServiceBindingLocked回到目标进程内

Copy
// ActiveServices.java

private final boolean requestServiceBindingLocked(ServiceRecord r,
IntentBindRecord i,
boolean execInFg,
boolean rebind) throws TransactionTooLargeException {

// 检查 ProcessRecord & 其中的 Service#IApplicationThread 是否存在
if (r.app == null || r.app.getThread() == null) {
// If service is not currently running, can't yet bind.
return false;
}

... Bebug 訊息

// 客户端没绑定过or呼叫Service要重新绑定
if ((!i.requested || rebind) && i.apps.size() > 0) {

try {
// 通知 IApplicationThread (App端实线) 的 scheduleBindService 方法

// 分析 scheduleBindService 方法
r.app.getThread().scheduleBindService(r, i.intent.getIntent(), rebind,
r.app.mState.getReportedProcState());

if (!rebind) {
i.requested = true;
}

i.hasBound = true;
i.doRebind = false;
} /* 省略 catch */
}

return true;
}

App 进程 - Service#onBind 呼叫

ActivityThread - scheduleBindService 进入 Service 所在进程做绑定
创建 BindServiceData 对象，储存 ServiceRecord & Intent 信息
Server 进程收到 Binder 通信通知后，透过 Handler 对主线程发送 BIND_SERVICE 信息
主线程接收到 BIND_SERVICE 消息后，呼叫 handleBindService 方法，如果是第一次绑定就 1. 呼叫该 Service 的 onBind 方法，再接着 2. 呼叫AMS#publishService 方法

Copy
// ActivityThread.java

private class ApplicationThread extends IApplicationThread.Stub {

... 省略其他方法

public final void scheduleBindService(IBinder token, Intent intent,
boolean rebind, int processState) {
...

// 1. 创建BindServiceData对象，储存ServiceRecord & Intent
BindServiceData s = new BindServiceData();
// token 就是 ServiceRecord
s.token = token;
s.intent = intent;
s.rebind = rebind;

... Debug 訊息

// 2. 对主线程发送BIND_SERVICE信息
sendMessage(H.BIND_SERVICE, s);
}
}

class H extends Handler {

public static final int BIND_SERVICE = 121;

public void handleMessage(Message msg) {

... 省略其他 case

case BIND_SERVICE:
... 省略 trace

handleBindService((BindServiceData)msg.obj);
break;
}
}

private void handleBindService(BindServiceData data) {
// token 就是 ServiceRecord
CreateServiceData createData = mServicesData.get(data.token);

// 查看缓存
// mServices在handleCreateService时就会被添加
Service s = mServices.get(data.token);

// 若取不到，则代表Service尚未启动
if (s != null) {
try {
...

try {
if (!data.rebind) {
// 3. 第一次绑定就呼叫onBind、AMS#publishService方法
IBinder binder = s.onBind(data.intent);

// publishService代表Server已经启动
ActivityManager.getService().publishService(
data.token, data.intent, binder);
} else {
// 重新绑定则呼叫onRebind
s.onRebind(data.intent);
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
}
try {
// 通知AMS该Service正在运行中
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_START, data.startId, res);
} /* 省略 catch */
} /* 省略 catch */
}
}

Service 发布 - 通知所有使用者

若 Service 进程启动第一次启动，就会呼叫AMS#publishService方法

Copy
// ActivityManagerService.java

// token 就是 BindServiceData
public void publishService(IBinder token, Intent intent, IBinder service) {
// Refuse possible leaked file descriptors
if (intent != null && intent.hasFileDescriptors() == true) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}

synchronized(this) {
if (!(token instanceof ServiceRecord)) {
throw new IllegalArgumentException("Invalid service token");
}
// 分析 publishServiceLocked 方法
mServices.publishServiceLocked((ServiceRecord)token, intent, service);
}
}

ActiveServices)#publishServiceLocked 透过 ServiceRecord 取得所有与该 Serice 有连接的 APP 端，并逐一进行通知

Copy
// ActiveServices.java

// token 就是 BindServiceData
void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {

final long origId = Binder.clearCallingIdentity();
try {
... debug 訊息

if (r != null) {
...

// 取得该Service的绑定信息
IntentBindRecord b = r.bindings.get(filter);

if (b != null && !b.received) {
b.binder = service;
b.requested = true;
b.received = true;

// 透过ServiceRecord取得，所有与该Service联机的纪录
ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections = r.getConnections();

for (int conni = connections.size() - 1; conni >= 0; conni--) {
ArrayList<ConnectionRecord> clist = connections.valueAt(conni);
// 遍历每个联机纪录
for (int i=0; i<clist.size(); i++) {
// 当前联机纪录
ConnectionRecord c = clist.get(i);
...
try {
// conn 是 IServiceConnect
// 分析 IServiceConnect#connected 方法
c.conn.connected(r.name, service, false);
} /* 省略 catch */
}
}
}

...
}
} finally {
Binder.restoreCallingIdentity(origId);
}

}

启动 Service

Copy
public class TestService extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

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

ContextImpl startService 呼叫 AMS

透过 ActivityManager 作为代理类访问 AMS 的 startService 方法，这边可以看出来 startService 并没有回调，但是 可以通过返回 ComponentName 判断是否启动成功

Copy
// ContextImpl.java

@Override
public ComponentName startService(Intent service) {
...
return startServiceCommon(service, false, mUser);
}

private ComponentName startServiceCommon(Intent service, boolean requireForeground,
UserHandle user) {

try {
validateServiceIntent(service);
service.prepareToLeaveProcess(this);

// 透过代理类访问AMS#startService
ComponentName cn = ActivityManager.getService().startService(
mMainThread.getApplicationThread(), service,
service.resolveTypeIfNeeded(getContentResolver()), requireForeground,
getOpPackageName(), getAttributionTag(), user.getIdentifier());

if (cn != null) {
// 没有权限去启动Service
if (cn.getPackageName().equals("!")) {
throw new SecurityException(
"Not allowed to start service " + service
+ " without permission " + cn.getClassName());
} else if (cn.getPackageName().equals("!!")) {
// 无法启动Service
throw new SecurityException(
"Unable to start service " + service
+ ": " + cn.getClassName());
} else if (cn.getPackageName().equals("?")) {
// 不允许启动Service
throw ServiceStartNotAllowedException.newInstance(requireForeground,
"Not allowed to start service " + service + ": " + cn.getClassName());
}
}

... 省略部分

} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}

AMS - 启动 Service 过程

ActivityManagerService#startService
检查 Intent 是否包含 FileDescriptors
呼叫 ActiveServices#startServiceLocked 方法

Copy
// ActivityManagerService.java

final ActiveServices mServices;

@Override
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, boolean requireForeground, String callingPackage,
String callingFeatureId, int userId)
throws TransactionTooLargeException {

// 检查Intent
if (service != null && service.hasFileDescriptors() == true) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}

// 检查Package
if (callingPackage == null) {
throw new IllegalArgumentException("callingPackage cannot be null");
}

... debug 訊息

synchronized(this) {
// 取得呼叫者的 pid & uid
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();

final long origId = Binder.clearCallingIdentity();

ComponentName res;
try {
// mServices类型是ActiveServices
// 分析startServiceLocked方法
res = mServices.startServiceLocked(caller, service,
resolvedType, callingPid, callingUid,
requireForeground, callingPackage, callingFeatureId, userId);
} finally {
Binder.restoreCallingIdentity(origId);
}
return res;
}
}

ActiveServices
1. 检查目前装置（同样是透过 PKMS）是否有指定 Service，查看 retrieveServiceLocked 方法
2. 找到指定 ServiceRecord

Copy
// ActiveServices.java

// caller 是呼叫者
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
int callingPid, int callingUid, boolean fgRequired,
String callingPackage, @Nullable String callingFeatureId, final int userId,
boolean allowBackgroundActivityStarts, @Nullable IBinder backgroundActivityStartsToken)
throws TransactionTooLargeException {

... 省略部分

// 1. 检查目前装置是否有指定Service，查看retrieveServiceLocked方法
ServiceLookupResult res =
retrieveServiceLocked(service, null, resolvedType, callingPackage,
callingPid, callingUid, userId, true, callerFg, false, false);

// 找不到 Service
if (res == null) {
return null;
}

...

ServiceRecord r = res.record;

... 省略部分

// 2. 找到的ServiceRecord就是用于描述一个Service
return startServiceInnerLocked(r, service, callingUid, callingPid, fgRequired, callerFg,
allowBackgroundActivityStarts, backgroundActivityStartsToken);

}

ServiceRecord 用于描述一个 Service，类似于 ActivityRecord 描述一个 Activity

APP 端描述 | AMS 中描述
Activity | ActivityRecord
Service | ServiceRecord

ActiveServices - 透过 PKMS 找 Service

AMS 寻找 Service 的方法是 ServiceLoopupResult，目的是要找到 ServiceRecord，而 找到 ServiceRecord 主要透过 PKMS

Copy
// ActiveServices.java

private ServiceLookupResult retrieveServiceLocked(Intent service,
String instanceName, String resolvedType, String callingPackage,
int callingPid, int callingUid, int userId,
boolean createIfNeeded, boolean callingFromFg, boolean isBindExternal,
boolean allowInstant) {

// 每个Service都会转为ServiceRecord
ServiceRecord r = null;

ServiceMap smap = getServiceMapLocked(userId);

// 组装ComponentName
final ComponentName comp;

if (instanceName == null) { // 目前传入的instanceName是null
comp = service.getComponent();
} else {

// 透過 Component 組裝 ComponentName
final ComponentName realComp = service.getComponent();
if (realComp == null) {
throw new IllegalArgumentException("Can't use custom instance name '" + instanceName
+ "' without expicit component in Intent");
}
comp = new ComponentName(realComp.getPackageName(),
realComp.getClassName() + ":" + instanceName);
}

// 判断 ComponentName 结果
if (comp != null) {
r = smap.mServicesByInstanceName.get(comp);
}

... 省略部分

if (r == null) {
try {

...

// 透过 PackageManager 找对对应的 Service
ResolveInfo rInfo = mAm.getPackageManagerInternal().resolveService(service,
resolvedType, flags, userId, callingUid);

ServiceInfo sInfo = rInfo != null ? rInfo.serviceInfo : null;
if (sInfo == null) {
// 如果 PKMS 都找不到就直接返回 null
Slog.w(TAG_SERVICE, "Unable to start service " + service + " U=" + userId +
": not found");
return null;
}
... 省略部分

} catch (RemoteException ex) {
// 在同进程，所以一定不会发生
}
}

if (r != null) {
... 省略部分

return new ServiceLookupResult(r, null);
}

return null;

}

// Key 是 callingUser(int)
final SparseArray<ServiceMap> mServiceMap = new SparseArray<>();

private ServiceMap getServiceMapLocked(int callingUser) {
// 尝试取得缓存
ServiceMap smap = mServiceMap.get(callingUser);
if (smap == null) {
// 重新创建一个Service纪录对象
smap = new ServiceMap(mAm.mHandler.getLooper(), callingUser);
mServiceMap.put(callingUser, smap);
}
return smap;
}

final class ServiceMap extends Handler {
final int mUserId;
// 呼叫过的Service都会记录起来
final ArrayMap<ComponentName, ServiceRecord> mServicesByInstanceName = new ArrayMap<>();

... 省略部分

}

mServiceMap 主要是透过 User 作为 Key，储存相对应的 ServiceMap，内部又有储存 ComponentName & ServiceRecord，当 User 呼叫过相同的 Service 就可以透过它取得 Service 的缓存

Service 启动入口 - startServiceInnerLocked

Copy
// ActiveServices.java
final ActivityManagerService mAm;

ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {

// 这也是Function有Locked关键字的关系
synchronized (mAm.mProcessStats.mLock) {
final ServiceState stracker = r.getTracker();
if (stracker != null) {
stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity);
}
}
r.callStart = false;

final int uid = r.appInfo.uid;
final String packageName = r.name.getPackageName();
final String serviceName = r.name.getClassName();

... 省略部分

// 透过bringUpServiceLocked启动Service
String error = bringUpServiceLocked(r, service.getFlags(), callerFg,
false /* whileRestarting */,
false /* permissionsReviewRequired */,
false /* packageFrozen */,
true /* enqueueOomAdj */);

...

return r.name;

}

函数名 | 功能
bringUpServiceLocked | 判断 Process，若设为启动则透过 AMS 唤醒
bringDownServiceLocked | 取得连接该 Service 的所有联机，关闭 Service
bringUpServiceLocked 判断 Process 状态，若 Service 应在要所在的进程没有启动则透过 AMS 启动目标 Process |

Copy
// ActiveServices.java

private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
boolean whileRestarting, boolean permissionsReviewRequired, boolean packageFrozen,
boolean enqueueOomAdj)
throws TransactionTooLargeException {

... 省略判空、Log 訊息

// 该Service是否隔离
final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;

// 获取Service要运行在哪个进程
final String procName = r.processName;
HostingRecord hostingRecord = new HostingRecord("service", r.instanceName);
ProcessRecord app;

if (!isolated) {
// 1. 尝试透过AMS取得ProcessRecord对象
app = mAm.getProcessRecordLocked(procName, r.appInfo.uid);

if (app != null) { // ProcessRecord 存在

final IApplicationThread thread = app.getThread();
final int pid = app.getPid();
final UidRecord uidRecord = app.getUidRecord();

if (thread != null) {
try {
app.addPackage(r.appInfo.packageName, r.appInfo.longVersionCode,
mAm.mProcessStats);

// 2. realStartServiceLocked 真正启动 Service
realStartServiceLocked(r, app, thread, pid, uidRecord, execInFg,
enqueueOomAdj);

return null;
} /* 省略 catch*/

}
}
} else {
... 省略部分
}

if (app == null && !permissionsReviewRequired && !packageFrozen) {
// 目标process不存在就透过AMS#startProcessLocked启动
if ((app = mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
hostingRecord, ZYGOTE_POLICY_FLAG_EMPTY, false, isolated)) == null) {
... 啟動失敗

// 关闭Servcie
bringDownServiceLocked(r, enqueueOomAdj);
return msg;
}
if (isolated) {
r.isolatedProc = app;
}
}

... 省略部分
}

真正创建 Service - realStartServiceLocked

透过 ProcessRecord 中的 thread（也就是 AcitivtyThread 内的 ApplicationThread 对象）呼叫 scheduleCreateService 方法

Copy
// ActiveServices.java

private void realStartServiceLocked(ServiceRecord r, ProcessRecord app,
IApplicationThread thread, int pid, UidRecord uidRecord, boolean execInFg,
boolean enqueueOomAdj) throws RemoteException {

// 设定目标Process
r.setProcess(app, thread, pid, uidRecord);

... 省略部分

// 取得目标进程内所有的Services
final ProcessServiceRecord psr = app.mServices;

final boolean newService = psr.startService(r);
...

// 透过AMS调整OOM_ADJ的数值
mAm.enqueueOomAdjTargetLocked(app);
mAm.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_START_SERVICE);

boolean created = false;
try {

...

final int uid = r.appInfo.uid;
final String packageName = r.name.getPackageName();
final String serviceName = r.name.getClassName();

...

// thread 是 App 端的 IApplicationThread
thread.scheduleCreateService(r,
r.serviceInfo,
mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo),
app.mState.getReportedProcState());

...

created = true;
} /* 省略 catch、finally */

... 省略部分

}

ActivityThread - APP 端处理 scheduleCreateService，会透过 MainHandler 传送 CREATE_SERVICE 到主线程，之后就会呼叫到 handleCreateService 方法

Copy
// ActivityThread.java

private class ApplicationThread extends IApplicationThread.Stub {

public final void scheduleCreateService(IBinder token,
ServiceInfo info, CompatibilityInfo compatInfo, int processState) {

updateProcessState(processState, false);

// 将需要的数据封装成CreateServiceData类
CreateServiceData s = new CreateServiceData();
s.token = token; // Token 就是ServiceRecord类
s.info = info; // 包有 Service 的 class name ... 等等信息
s.compatInfo = compatInfo;

// 透过Hander传送CREATE_SERVICE信息
sendMessage(H.CREATE_SERVICE, s);
}

}

class H extends Handler {

public static final int CREATE_SERVICE = 114;

public void handleMessage(Message msg) {
switch (msg.what) {

case CREATE_SERVICE:
...

handleCreateService((CreateServiceData)msg.obj);
break;
}
}
}

@UnsupportedAppUsage
private void handleCreateService(CreateServiceData data) {
Service service = null;

LoadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo);

try {

Application app = packageInfo.makeApplication(false, mInstrumentation);

...

// 透过LoadedApk创建Servcie对象
// getAppFactory（）=>创建的是AppComponentFactory对象
service = packageInfo.getAppFactory()
.instantiateService(cl, data.info.name, data.intent);

// 创建对应的ContextImpl对象
ContextImpl context = ContextImpl.getImpl(service
.createServiceBaseContext(this, packageInfo));

// 呼叫 service#attach 方法
service.attach(context, this, data.info.name, data.token, app,
ActivityManager.getService());

// 呼叫 onCreate 方法
service.onCreate();

try {
// 通知AMS，Service创建成功
// data.token就是ServiceRecord
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}

} /* 省略 catch */
}

透过 LoadedApk 创建 Service 对象

Copy
// LoadedApk.java
private AppComponentFactory mAppComponentFactory;

public LoadedApk(ActivityThread activityThread, ApplicationInfo aInfo,
CompatibilityInfo compatInfo, ClassLoader baseLoader,
boolean securityViolation, boolean includeCode, boolean registerPackage) {
mActivityThread = activityThread;
// Default ApplicationInfo
mApplicationInfo = new ApplicationInfo();

...

// 透过createAppFactory方法创建Factory
mAppComponentFactory = createAppFactory(mApplicationInfo, mBaseClassLoader);
}

public AppComponentFactory getAppFactory() {
return mAppComponentFactory;
}

private AppComponentFactory createAppFactory(ApplicationInfo appInfo, ClassLoader cl) {

// 若有自定义Factory则透过反射创建
if (mIncludeCode && appInfo.appComponentFactory != null && cl != null) {
try {
return (AppComponentFactory)
cl.loadClass(appInfo.appComponentFactory).newInstance();
} /* 省略部分 */
}

// 预设Factory
return AppComponentFactory.DEFAULT;
}

预设工厂 AppComponentFactory：透过ClassLoader#loadClass读取指定 Class，并透过反射创建指定类

Copy
// AppComponentFactory.java

public class AppComponentFactory {

... 省略部分

public @NonNull Service instantiateService(@NonNull ClassLoader cl,
@NonNull String className, @Nullable Intent intent)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
// 透过ClassLoader#loadClass读取指定Class，并透过反射创建该类
return (Service) cl.loadClass(className).newInstance();
}

// 预设Factory
public static final AppComponentFactory DEFAULT = new AppComponentFactory();
}