Service 启动过程

看完 Activity 的启动过程,发现 Service 的启动过程相对来说就比较简单了。

要说起启动过程,就得从 startService 开始:

1.startService

根据源码的跳转,发现跳转到 ContextWrapper 这个类中,代码如下:

1
2
3
4
@Override
public ComponentName startService(Intent service) {
return mBase.startService(service);
}

其中 mBase 是类型是:Context 类型,如下:

1
2
3
4
public class ContextWrapper extends Context {
Context mBase;
......
}

而我们又知道 Context 是一个抽象类 ,实现者是 ContextImpl ,所以我们应该是查看ContextImpl 这个类中的 startService(service) 方法。

ContextImpl 中的方法定义如下:

1
2
3
4
5
@Override
public ComponentName startService(Intent service) {
warnIfCallingFromSystemProcess();
return startServiceCommon(service, false, mUser);
}

startService 中又调用了 startServiceCommon(service,(requirForeground:false),mUser) 这个方法,继续跟进:

2.startServiceCommon

startServiceCommon 方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
private ComponentName startServiceCommon(Intent service, boolean requireForeground,
UserHandle user) {
try {
//校验要启动的service
validateServiceIntent(service);
service.prepareToLeaveProcess(this);
ComponentName cn = ActivityManager.getService().startService(
mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
getContentResolver()), requireForeground,
getOpPackageName(), user.getIdentifier());
if (cn != null) {
if (cn.getPackageName().equals("!")) {
throw new SecurityException(
"Not allowed to start service " + service
+ " without permission " + cn.getClassName());
} else if (cn.getPackageName().equals("!!")) {
throw new SecurityException(
"Unable to start service " + service
+ ": " + cn.getClassName());
} else if (cn.getPackageName().equals("?")) {
throw new IllegalStateException(
"Not allowed to start service " + service + ": " + cn.getClassName());
}
}
return cn;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}

这里面有几个需要说明一下:

  • ActivityManager.getService() 点进去查看
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    /**
    * @hide
    */
    public static IActivityManager getService() {
    return IActivityManagerSingleton.get();
    }

    private static final Singleton<IActivityManager> IActivityManagerSingleton =
    new Singleton<IActivityManager>() {
    @Override
    protected IActivityManager create() {
    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
    final IActivityManager am = IActivityManager.Stub.asInterface(b);
    return am;
    }
    };

首先是返回的类型是 IActivityManager 类型,其中在create 方法中,拿到远程服务的Binder 对象,其中IActivityManager.Stub.asInterface(b) 不知道大家有没有想起AIDL 这就很熟悉了,就是拿到远程服务的代理对象:IActivityManager,通过代理对象调用远程的方法,是应用进程与服务进程通信的媒介,如果没猜错的话就是在ActivityManagerService 中实现了,查看ActivityManagerService 类:

1
2
3
4
public class ActivityManagerService extends IActivityManager.Stub
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
.....
}

果然不出所料,AMS extend IActivityManager.Stub .

  • mMainThread.getApplicationThread() 首先明白 mMainThreadActivityThread 类的实例变量,通过getApplicationThread() 方法拿到一个 ApplicationThread 类的实例:
    1
    2
    3
    4
    public ApplicationThread getApplicationThread()
    {
    return mAppThread;
    }

ApplicationThread 类定义如下:

1
2
3
private class ApplicationThread extends IApplicationThread.Stub {
.....
}

发现 ApplicationThreadActivityThread 的一个内部类.并且实现了 IApplicationThread.Stub ,而我们又把这个类型传入给了AMS,相当于远程服务拿到了一个访问应用进程的代理,类型为:IApplicationThread

总结:到目前为止,客户端拿到了远程服务的代理(IActivityManager), 服务端拿到了客户端的代理(IApplicationThread),它们互相拿到各自进程的代理类,是它们进行进程间通信的基础。

ok ,我们回到最初那个地方:

1
2
3
4
ComponentName cn = ActivityManager.getService().startService(
mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
getContentResolver()), requireForeground,
getOpPackageName(), user.getIdentifier());

通过前面的分析我们知道:ActivityManager.getService(). 实际就是 AMS 远程代理,最终在AMS 中完成,我们去 AMS 代码中查看下 startService 代码:

3.ActivityManagerService. startService

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
@Override
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, boolean requireForeground, String callingPackage, int userId)
throws TransactionTooLargeException {
enforceNotIsolatedCaller("startService");
// Refuse possible leaked file descriptors
if (service != null && service.hasFileDescriptors() == true) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}

if (callingPackage == null) {
throw new IllegalArgumentException("callingPackage cannot be null");
}

if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
"*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
synchronized(this) {
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
ComponentName res;
try {
// 又调用了startServiceLocked 方法
res = mServices.startServiceLocked(caller, service,
resolvedType, callingPid, callingUid,
requireForeground, callingPackage, userId);
} finally {
Binder.restoreCallingIdentity(origId);
}
return res;
}
}

startServiceLocked 方法很复杂,大概如下:

1
2
3
4
5
6
7
8
9
10
11
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId)
throws TransactionTooLargeException {

.....
ServiceRecord r = res.record;//启动service的信息保存在 serviceRecord 中
....
ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
return cmp;
.....
}

内部又调用了:startServiceInnerLocked 方法

4.startServiceInnerLocked

如下:

1
2
3
4
5
6
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
...
String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
...
}

又调用: bringUpServiceLocked

5.bringUpServiceLocked

1
2
3
4
5
6
7
 private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
boolean whileRestarting, boolean permissionsReviewRequired)
throws TransactionTooLargeException {
....

realStartServiceLocked(r, app, execInFg);
}

而后又调用了 realStartServiceLocked(r, app, execInFg);

6.realStartServiceLocked

1
2
3
4
5
6
7
8
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
....
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
app.repProcState);
....
}

其中 app.threadIApplicationThread 类型,就是远程调用客户端进程里的方法,scheduleCreateService ,而我们又知道 ApplicationThread 实现了 IApplicationThread,所以就查看 ApplicationThread 类中的 scheduleCreateService方法,前面我们说过ApplicationThreadActivityThread 的一个内部类,查看:

7.ApplicationThread.scheduleCreateService

1
2
3
4
5
6
7
8
9
10
public final void scheduleCreateService(IBinder token,
ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
updateProcessState(processState, false);
CreateServiceData s = new CreateServiceData();
s.token = token;
s.info = info;
s.compatInfo = compatInfo;

sendMessage(H.CREATE_SERVICE, s);
}

发现内部通过发送一个 CREATE_SERVICE 的消息,HHandle,继续查看:
handleMessage 方法

1
2
3
4
5
case CREATE_SERVICE:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));
handleCreateService((CreateServiceData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;

handleCreateService 中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
private void handleCreateService(CreateServiceData data) {
// If we are getting ready to gc after going to the background, well
// we are back active so skip it.
unscheduleGcIdler();

LoadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo);
Service service = null;
try {
java.lang.ClassLoader cl = packageInfo.getClassLoader();
service = (Service) cl.loadClass(data.info.name).newInstance();
} catch (Exception e) {
if (!mInstrumentation.onException(service, e)) {
throw new RuntimeException(
"Unable to instantiate service " + data.info.name
+ ": " + e.toString(), e);
}
}

try {
if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
//创建context
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(service);
//创建Application
Application app = packageInfo.makeApplication(false, mInstrumentation);
//通过attach 方法,将context application ,service 连接起来
service.attach(context, this, data.info.name, data.token, app,
ActivityManager.getService());
//调用service oncreate方法
service.onCreate();
mServices.put(data.token, service);
try {
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
} catch (Exception e) {
if (!mInstrumentation.onException(service, e)) {
throw new RuntimeException(
"Unable to create service " + data.info.name
+ ": " + e.toString(), e);
}
}
}

service.onCreate(); ok ,调用了 onCreate 方法,至此,service的启动过程的就完成了。

-------------本文结束感谢您的阅读-------------