前言

本文分析源码来自android 9.0

启动分析

Service start时序图

如果直接调用startService来启动Service,一个完整流程大致如上时序图所示。主要经历了创建 Service,绑定Service,执行Start任务的三个过程。

创建初始化

Service 和Activity都是继承于ContextWrapper,创建Service的请求实际是ContextWrapper发出,ContextWrapper将交给 一个mBase的Context去调用,这个Context的具体实现其实是ContextImpl,在组件被创建时在其attachBaseContext 中被赋值

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
//ContextWrapper.java
protected void attachBaseContext(Context base) {
    if (mBase != null) {
        throw new IllegalStateException("Base context already set");
    }
    mBase = base;
}

//Activity.java
final void attach(Context context,...) {
        attachBaseContext(context);
}

//ActivityThread.java
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    ...
    ContextImpl appContext = createBaseContextForActivity(r);
    ...
    activity.attach(appContext, ...);
    ...
}

在ContextImpl中继续调用startServiceCommon来传递命令,之后就开始Binder请求向AMS发送命令。

1
2
3
4
5
6
7
8
private ComponentName startServiceCommon(Intent service, boolean requireForeground,UserHandle user) {
    ...
     ComponentName cn = ActivityManager.getService().startService(
                mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
                            getContentResolver()), requireForeground,
                            getOpPackageName(), user.getIdentifier());
    ...
}

到了AMS,也是继续分发,这里是交给一个ActiveServices的类来管理,基本所有有关于Service的业务都是经过ActiveServices来 处理。

1
2
3
4
5
6
7
8
9
//ActivityManagerService.java

final ActiveServices mServices;

public ComponentName startService(IApplicationThread caller, Intent service,String resolvedType, boolean requireForeground, String callingPackage, int userId)throws TransactionTooLargeException {
    ...
    res = mServices.startServiceLocked(caller, service,resolvedType, callingPid, callingUid,requireForeground, callingPackage, userId);
    ...
}

继续分发给了ActiveServices的startServiceInnerLocked,在启动之前会对所操作的Service的信息进行一个校验。之后会调用 bringUpServiceLocked,这时才真正进入创建Service的时候。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
//ActiveService.java
ComponentName startServiceLocked(...)throws TransactionTooLargeException {
    ...
    //对Service的信息一个校验
    ServiceLookupResult res = retrieveServiceLocked(service, resolvedType, callingPackage,callingPid, callingUid, userId, true, callerFg, false, false);
    ...
    //启动
    ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
    ...
}

ComponentName startServiceInnerLocked(...) throws TransactionTooLargeException {
        ServiceState stracker = r.getTracker();
        ...
        String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
        ...
    }

在bringUpServiceLocked中,比较重要的两个地方,如下在最开始会判断ServiceRecord的一个对象r的存在情况, 只要ServiceRecord这些信息健全,就表示Service已经存在,就直接用sendServiceArgsLocked,这个sendServiceArgsLocked 方法会直接触发Service的onStartCommand的回调,后边也会继续分析解释。

再者就进入realStartServiceLocked方法,光看名字就知道realStartServiceLocked才是真正的主角。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
 private String bringUpServiceLocked(...)throws TransactionTooLargeException {
     ...
     if (r.app != null && r.app.thread != null) {
        sendServiceArgsLocked(r, execInFg, false);
        return null;
     }
     ...
     realStartServiceLocked(r, app, execInFg);
     ...
}

创建

在realStartServiceLocked中开始真正的创建工作。

1
2
3
4
5
6
7
//ActiveServices.java
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.thread就是IApplicationThread,将创建任务指令发送给了ApplicationThread。ApplicationThread向H发送 CREATE_SERVICE消息,最终调用了ActivityThread的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
public final class ActivityThread extends ClientTransactionHandler {

    ...
    final H mH = new H();
    ...

    private void handleCreateService(CreateServiceData data) {
        ...
         ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
         context.setOuterContext(service);

         Application app = packageInfo.makeApplication(false, mInstrumentation);
         service.attach(context, this, data.info.name, data.token, app,ActivityManager.getService());
         service.onCreate();
         mServices.put(data.token, service);
        ...
    }
    ...
    private class ApplicationThread extends IApplicationThread.Stub {
        public final void scheduleCreateService(IBinder token,ServiceInfo info, CompatibilityInfo compatInfo, int processState){
            ...
            sendMessage(H.CREATE_SERVICE, s);
        }
    }
    ...
}

一个比较值得注意的地方,一个Service的创建的同时会为其新创建一个Application对象,其实每个ActivityThread中都有一个Application 的集合,用于保存这些在组件创建中产生的Application。

然后Service调用了attach方法,绑定关系,主要是将各个主要进程对象绑定到Service上,在9.0的源码中我们发现该方法有一个@hide注解, 一般有这个注解的都是不能直接反射。新版的android sdk对这些方法都是管理比较严格

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
 /**
     * @hide
     */
    public final void attach(
            Context context,
            ActivityThread thread, String className, IBinder token,
            Application application, Object activityManager) {
        attachBaseContext(context);
        mThread = thread;           // NOTE:  unused - remove?
        mClassName = className;
        mToken = token;
        mApplication = application;
        mActivityManager = (IActivityManager)activityManager;
        mStartCompatibility = getApplicationInfo().targetSdkVersion
                < Build.VERSION_CODES.ECLAIR;
    }

然后Servide就会执行我们最熟悉的onCreate方法,这里完成我们的初始化代码,最后binder通讯向AMS调用serviceDoneExecuting

绑定

我们需要再回到ActiveServices的realStartServiceLocked方法中,在上述创建之后,会继续执行到requestServiceBindingsLocked 方法。

 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
//ActiveServices.java
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);
    ...
    requestServiceBindingsLocked(r, execInFg);
    ...
}

private final void requestServiceBindingsLocked(ServiceRecord r, boolean execInFg)
            throws TransactionTooLargeException {
        for (int i=r.bindings.size()-1; i>=0; i--) {
            IntentBindRecord ibr = r.bindings.valueAt(i);
            if (!requestServiceBindingLocked(r, ibr, execInFg, false)) {
                break;
            }
        }
    }

private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,boolean execInFg, boolean rebind) throws TransactionTooLargeException {
    ...
    r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
                        r.app.repProcState);
    ...
}

在创建完Service之后,会执行requestServiceBindingsLocked方法,该方法会循环遍历Service的绑定 关系集合,依次执行绑定操作requestServiceBindingLocked,在requestServiceBindingLocked中 最终会通过Binder执行ApplicationThread的scheduleBindService。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
public final class ActivityThread extends ClientTransactionHandler {

    ...
    final H mH = new H();
    ...

    private void handleBindService(BindServiceData data) {
        Service s = mServices.get(data.token);
        ...
        IBinder binder = s.onBind(data.intent);
        ActivityManager.getService().publishService(data.token, data.intent, binder);
        ...
    }
    ...
    private class ApplicationThread extends IApplicationThread.Stub {
        public final void scheduleBindService(IBinder token,ServiceInfo info, CompatibilityInfo compatInfo, int processState){
            ...
            sendMessage(H.BIND_SERVICE, s);
        }
    }
    ...
}

在回调了Service的onBind之后,会让AMS 发出一个publishService操作,当然真正执行操作还是ActiveServices

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
//ActiveServices.java
 void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
        ...
        Intent.FilterComparison filter = new Intent.FilterComparison(intent);
        IntentBindRecord b = r.bindings.get(filter);
        for (int conni=r.connections.size()-1; conni>=0; conni--) {
            ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);
            for (int i=0; i<clist.size(); i++) {
                ConnectionRecord c = clist.get(i);
                if (!filter.equals(c.binding.intent.intent)) {
                    ...            
                    c.conn.connected(r.name, service, false);
                    ...
                }
            }
        }
        ...
    }

该方法会遍历所有绑定链接集合,然后重新链接。其中的ConnectionRecord的conn其实是在LoadApk中的一个 内部类InnerConnection,最终调用的是ServiceDispatcher的connected方法。

 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
public final class LoadedApk {
    ...
    static final class ServiceDispatcher {
        ...
        private static class InnerConnection extends IServiceConnection.Stub {
            final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;

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

            public void connected(ComponentName name, IBinder service, boolean dead)
                    throws RemoteException {
                LoadedApk.ServiceDispatcher sd = mDispatcher.get();
                if (sd != null) {
                    sd.connected(name, service, dead);
                }
            }
        }
        ...

        public void connected(ComponentName name, IBinder service, boolean dead) {
            ...                
            doConnected(name, service, dead);
        }

        public void doConnected(ComponentName name, IBinder service, boolean dead) {
            ...
            if (service != null) {
                mConnection.onServiceConnected(name, service);
            }
        }
    }
    ...
}

在调用了doConnected之后,会最终调用ServiceConnection的onServiceConnected的方法,将service的binder 对象传入。

Start任务

然后我们再回到ActiveServices的realStartServiceLocked方法中,再完成了上述两步之后,接着会调用到sendServiceArgsLocked。 我们之前提到过在创建Service之前会判断Service本身是否存在,如果存在就直接调用该方法,那该方法会完成什么操作呢?

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
//ActiveServices.java
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);
    ...
    requestServiceBindingsLocked(r, execInFg);
    ...
    sendServiceArgsLocked(r, execInFg, true);
    ...
}
1
2
3
4
5
6
//ActiveServices.java
private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,boolean oomAdjusted) throws TransactionTooLargeException {
    ...
    r.app.thread.scheduleServiceArgs(r, slice);
    ...
}

在sendServiceArgsLocked方法中最关键的步骤还是调用了ApplicationThread的scheduleServiceArgs。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
public final class ActivityThread extends ClientTransactionHandler {

    ...
    final H mH = new H();
    ...

     private void handleServiceArgs(ServiceArgsData data) {
        Service s = mServices.get(data.token);
        ...        
        res = s.onStartCommand(data.args, data.flags, data.startId); 
        ...
    }
    ...
    private class ApplicationThread extends IApplicationThread.Stub {
        public final void scheduleServiceArgs(IBinder token, ParceledListSlice args) {
            ...
            sendMessage(H.SERVICE_ARGS, s);
        }
    }
    ...
}

不出所料,scheduleServiceArgs经过分发,最终会触发到Service的onStartCommand的回调,我们在这里面实现的 Service任务代码开始执行。同时会得到一个返回值,通过serviceDoneExecutingLocked方法将返回值继续传给AMS

 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
 void serviceDoneExecutingLocked(ServiceRecord r, int type, int startId, int res) {
        ...
        switch (res) {
            case Service.START_STICKY_COMPATIBILITY:
            case Service.START_STICKY: {
                r.findDeliveredStart(startId, false, true);
                r.stopIfKilled = false;
                break;
            }
            case Service.START_NOT_STICKY: {
                r.findDeliveredStart(startId, false, true);
                if (r.getLastStartId() == startId) {
                    r.stopIfKilled = true;
                }
                break;
            }
            case Service.START_REDELIVER_INTENT: {
                ServiceRecord.StartItem si = r.findDeliveredStart(startId, false, false);
                if (si != null) {
                    si.deliveryCount = 0;
                    si.doneExecutingCount++;
                    r.stopIfKilled = true;
                }
                break;
            }
            case Service.START_TASK_REMOVED_COMPLETE: {
                r.findDeliveredStart(startId, true, true);
                break;
            }
            default:
            throw new IllegalArgumentException("Unknown service start result: " + res);
      ...
    }

返回值的处理就是Service的几种模式描述的处理,对比代码,发现基本是改变ServiceRecord的stopIfKilled。当我搜索源码时 只发现在ActiveServices中的killServicesLocked方法中发挥作用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
final void killServicesLocked(ProcessRecord app, boolean allowRestart) {
    ...
    if (sr.startRequested && (sr.stopIfKilled || canceled)) {
        if (sr.pendingStarts.size() == 0) {
            sr.startRequested = false;
            if (sr.tracker != null) {
                sr.tracker.setStarted(false, mAm.mProcessStats.getMemFactorLocked(),SystemClock.uptimeMillis());
            }
            if (!sr.hasAutoCreateConnections()) {
                bringDownServiceLocked(sr);
            }
        }
    }  
    ...  
}

这个地方只是决定了在清理服务时会不会直接清理的逻辑,而对于Service的关于STICKY的几种模式的描述还是不能很好的理解, 只能留下一个疑问了。

停止分析

Service stop时序图

发出停止命令

命令还是由ContextImpl发出,将stopService的命令通过Binder发送给AMS,AMS会继续分发,最终调用 ActiveServices的bringDownServiceLocked。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//ContextImpl.java
 private boolean stopServiceCommon(Intent service, UserHandle user) {
    ...
    int res = ActivityManager.getService().stopService(
                mMainThread.getApplicationThread(), service,
                service.resolveTypeIfNeeded(getContentResolver()), user.getIdentifier());
    ...
}
//ActivityManagerService.java
 public int stopService(IApplicationThread caller, Intent service,
            String resolvedType, int userId) {
    ...
    return mServices.stopServiceLocked(caller, service, resolvedType, userId);
}
//ActiveServices.java
private void stopServiceLocked(ServiceRecord service) {
    ...   
    bringDownServiceIfNeededLocked(service, false, false);
}
private final void bringDownServiceIfNeededLocked(ServiceRecord r, boolean knowConn,boolean hasConn) {
    ...
    bringDownServiceLocked(r);
}

断开链接

在bringDownServiceLocked中会先断开service的所有链接。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
private final void bringDownServiceLocked(ServiceRecord r) {
    for (int conni=r.connections.size()-1; conni>=0; conni--) {
        ArrayList<ConnectionRecord> c = r.connections.valueAt(conni);
        for (int i=0; i<c.size(); i++) {
            ConnectionRecord cr = c.get(i);
            cr.serviceDead = true;
            ...
            cr.conn.connected(r.name, null, true);
            ...
        }
    }
}

在图中代码cr.conn.connected(r.name, null, true);会接着走每个绑定关系的ServiceConnection的 onServiceDisconnected,告诉客户端Service链接断开。

1
2
3
4
5
6
7
public void doConnected(ComponentName name, IBinder service, boolean dead) {
    ...
    if (old != null) {
        mConnection.onServiceDisconnected(name);
    }
    ...
}

解绑

再回到bringDownServiceLocked方法中,会通过onUnBind回调告诉Service完成解绑操作

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
private final void bringDownServiceLocked(ServiceRecord r) {
    for (int conni=r.connections.size()-1; conni>=0; conni--) {
        ArrayList<ConnectionRecord> c = r.connections.valueAt(conni);
        for (int i=0; i<c.size(); i++) {
            ConnectionRecord cr = c.get(i);
            cr.serviceDead = true;
            ...
            cr.conn.connected(r.name, null, true);
            ...
        }
    }
    ...
    r.app.thread.scheduleUnbindService(r,ibr.intent.getIntent());
    ...
}

继续通过binder通讯调用ApplicaitonThread的scheduleUnbindService来完成分发。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public final class ActivityThread extends ClientTransactionHandler {

    ...
    final H mH = new H();
    ...

     private void handleUnbindService(ServiceArgsData data) {
        Service s = mServices.get(data.token);
        ...        
        boolean doRebind = s.onUnbind(data.intent);
        ...
        ActivityManager.getService().serviceDoneExecuting(data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
        ...
    }
    ...
    private class ApplicationThread extends IApplicationThread.Stub {
        public final void scheduleUnbindService(IBinder token, ParceledListSlice args) {
            ...
            sendMessage(H.UNBIND_SERVICE, s);
        }
    }
    ...
}

停止

最后发出停止操作,调用Service的onDrstory的回调,完成销毁操作

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
private final void bringDownServiceLocked(ServiceRecord r) {
    for (int conni=r.connections.size()-1; conni>=0; conni--) {
        ArrayList<ConnectionRecord> c = r.connections.valueAt(conni);
        for (int i=0; i<c.size(); i++) {
            ConnectionRecord cr = c.get(i);
            cr.serviceDead = true;
            ...
            cr.conn.connected(r.name, null, true);
            ...
        }
    }
    ...
    r.app.thread.scheduleUnbindService(r,ibr.intent.getIntent());
    ...
    r.app.thread.scheduleStopService(r);
    ...
}

调用ApplicaitonThread的scheduleStopService来完成分发。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public final class ActivityThread extends ClientTransactionHandler {

    ...
    final H mH = new H();
    ...

     private void handleStopService(ServiceArgsData data) {
        Service s = mServices.get(data.token);
        ...        
        s.onDestroy();
        ...
        ActivityManager.getService().serviceDoneExecuting(data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
        ...
    }
    ...
    private class ApplicationThread extends IApplicationThread.Stub {
        public final void scheduleStopService(IBinder token, ParceledListSlice args) {
            ...
            sendMessage(H.STOP_SERVICE, s);
        }
    }
    ...
}

总结

分析完这样一个大流程,其实心很累,就像从一顿的棉花中,废了大力气,才挤了几滴水的感觉。分析Service启动过程产生了很多疑问,但是这些疑问都是 无法立马得到验证,最后只能对过程有个大概的了解。android系统源码庞大,只能一步一步慢慢的分析了。加油!