Android 6.0 Service 启动过程源码分析(一)

目录

技术答疑,成长进阶,可以加入我的知识星球:音视频领域专业问答的小圈子

Service 组件也是 Android 四大组件之一,它的启动过程分为显示和隐式两种。对于隐式启动的 Service 组件来说,我们只需要它的组件名称;对于显示启动的 Service 组件来说,我们需要知道它的类名称。

Service 组件可以被 Activity 组件启动,也可以被其他的 Service 组件启动。同时,它既可以在启动它的 Activity 组件或者 Service 组件所在的应用程序中启动,也可以在一个新的应用程序进程中启动。

Service 组件在新进程中的启动过程

不管 Service 组件是在 Activity 组件中启动的还是在 Service 组件中启动的,它们都是继承自ContextWrapper类的,最后调用的还是ContextImplstartService方法。

所以直接从ContextImpl方法开始分析即可。

ContextImpl 类的 startService() 方法

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

显然最后还是调用的startServiceCommon方法了。

ContextImpl 类的 startServiceCommon() 方法

 1private ComponentName startServiceCommon(Intent service, UserHandle user) {
 2        try {
 3            validateServiceIntent(service);
 4            service.prepareToLeaveProcess();
 5            // 向 ActivityManagerService 发送请求启动 Service 组件
 6            ComponentName cn = ActivityManagerNative.getDefault().startService(
 7                mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
 8                            getContentResolver()), getOpPackageName(), user.getIdentifier());
 9            if (cn != null) {
10                if (cn.getPackageName().equals("!")) {
11                    throw new SecurityException( "Not allowed to start service " + service
12                            + " without permission " + cn.getClassName());
13                } else if (cn.getPackageName().equals("!!")) {
14                    throw new SecurityException( "Unable to start service " + service
15                            + ": " + cn.getClassName());
16                }
17            }
18            return cn;
19        } catch (RemoteException e) {
20            throw new RuntimeException("Failure from system", e);
21        }
22    }
JAVA

startServiceCommon方法内又是 IPC 进程间通信了,通过ActivityManagerProxy向 Binder 驱动发送类型为START_SERVICE_TRANSACTION的消息,在ActivityManagerService响应对应消息。

ActivityManagerService 类的 startService() 方法

 1public ComponentName startService(IApplicationThread caller, Intent service,
 2            String resolvedType, String callingPackage, int userId)
 3            throws TransactionTooLargeException {
 4        enforceNotIsolatedCaller("startService");
 5        // Refuse possible leaked file descriptors
 6        if (service != null && service.hasFileDescriptors() == true) {
 7            throw new IllegalArgumentException("File descriptors passed in Intent");
 8        }
 9
10        if (callingPackage == null) {
11            throw new IllegalArgumentException("callingPackage cannot be null");
12        }
13        synchronized(this) {
14            final int callingPid = Binder.getCallingPid();
15            final int callingUid = Binder.getCallingUid();
16            final long origId = Binder.clearCallingIdentity();
17            ComponentName res = mServices.startServiceLocked(caller, service,
18                    resolvedType, callingPid, callingUid, callingPackage, userId);
19            Binder.restoreCallingIdentity(origId);
20            return res;
21        }
22    }
JAVA

在 ActivityManagerService 内又是调用 ActivityServices 类的 startServiceLocked() 方法,将调用者的piduid传入。

ActiveServices 类的 startServiceLocked() 方法

 1    ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
 2            int callingPid, int callingUid, String callingPackage, int userId)
 3            throws TransactionTooLargeException {
 4        final boolean callerFg;
 5        if (caller != null) {
 6            final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
 7            if (callerApp == null) {
 8                throw new SecurityException("");// 省略字符串内容
 9            }
10            callerFg = callerApp.setSchedGroup != Process.THREAD_GROUP_BG_NONINTERACTIVE;
11        } else {
12            callerFg = true;
13        }
14        // 查找是否存在于 service 对应的 ServiceRecord 对象,没有则封装一个
15        ServiceLookupResult res =
16            retrieveServiceLocked(service, resolvedType, callingPackage,
17                    callingPid, callingUid, userId, true, callerFg);
18        if (res == null) {
19            return null;
20        }
21        if (res.record == null) {
22            return new ComponentName("!", res.permission != null
23                    ? res.permission : "private to package");
24        }
25        ServiceRecord r = res.record;
26        if (!mAm.getUserManagerLocked().exists(r.userId)) { // 用户是否存在检查
27            Slog.d(TAG, "Trying to start service with non-existent user! " + r.userId);
28            return null;
29        }
30
31        NeededUriGrants neededGrants = mAm.checkGrantUriPermissionFromIntentLocked(
32                callingUid, r.packageName, service, service.getFlags(), null, r.userId);
33        if (unscheduleServiceRestartLocked(r, callingUid, false)) {
34            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "START SERVICE WHILE RESTART PENDING: " + r);
35        }
36        r.lastActivity = SystemClock.uptimeMillis();
37        r.startRequested = true;
38        r.delayedStop = false;
39        r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
40                service, neededGrants));
41
42        final ServiceMap smap = getServiceMap(r.userId);
43        boolean addToStarting = false;
44        if (!callerFg && r.app == null && mAm.mStartedUsers.get(r.userId) != null) {
45            ProcessRecord proc = mAm.getProcessRecordLocked(r.processName, r.appInfo.uid, false);
46            if (proc == null || proc.curProcState > ActivityManager.PROCESS_STATE_RECEIVER) {
47                if (r.delayed) {
48                    // This service is already scheduled for a delayed start; just leave
49                    // it still waiting.
50                    return r.name;
51                }
52                if (smap.mStartingBackground.size() >= mMaxStartingBackground) {
53                    // Something else is starting, delay!
54                    smap.mDelayedStartList.add(r);
55                    r.delayed = true;
56                    return r.name;
57                }
58                addToStarting = true;
59            } else if (proc.curProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
60                addToStarting = true;
61            } 
62        } 
63
64        return startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
65    }
JAVA

startServiceLocked 方法内的调用 retrieveServiceLocked方法在 ActivityManagerService 检查是否存在与参数 service对应的一个ServiceRecord对象。如果不存在,那么 ActivityManagerService 就会到 PackageManagerService 中去获取与参数service对应的一个 Service 组件的信息,然后将这些信息封装成一个ServiceRecord对象,最后将这个ServiceRecord对象封装成一个ServiceLookupResult对象返回给调用者。

接着就是对用户是否存在进行检查,最后调用startServiceInnerLocked方法。

ActiveServices 类的 startServiceInnerLocked() 方法

 1 ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
 2            boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
 3        ProcessStats.ServiceState stracker = r.getTracker();
 4        if (stracker != null) {
 5            stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity);
 6        }
 7        r.callStart = false;
 8        synchronized (r.stats.getBatteryStats()) {
 9            r.stats.startRunningLocked();
10        }
11        String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false);
12        if (error != null) {
13            return new ComponentName("!!", error);
14        }
15
16        if (r.startRequested && addToStarting) {
17            boolean first = smap.mStartingBackground.size() == 0;
18            smap.mStartingBackground.add(r);
19            r.startingBgTimeout = SystemClock.uptimeMillis() + BG_START_TIMEOUT;
20            if (first) {
21                smap.rescheduleDelayedStarts();
22            }
23        } else if (callerFg) {
24            smap.ensureNotStartingBackground(r);
25        }
26        return r.name;
27    }
JAVA

该方法内调用bringUpServiceLocked方法。

ActiveServices 类的 bringUpServiceLocked() 方法

 1private final String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
 2            boolean whileRestarting) throws TransactionTooLargeException {
 3
 4        if (r.app != null && r.app.thread != null) {// 满足条件,执行 service 的 onStartCommand 方法
 5            sendServiceArgsLocked(r, execInFg, false);
 6            return null;
 7        }
 8
 9        if (!whileRestarting && r.restartDelay > 0) {
10            // If waiting for a restart, then do nothing.
11            return null;
12        }
13        // We are now bringing the service up, so no longer in the
14        // restarting state.
15        if (mRestartingServices.remove(r)) {
16            r.resetRestartCounter();
17            clearRestartingIfNeededLocked(r);
18        }
19
20        // Make sure this service is no longer considered delayed, we are starting it now.
21        if (r.delayed) {
22            getServiceMap(r.userId).mDelayedStartList.remove(r);
23            r.delayed = false;
24        }
25
26        // Make sure that the user who owns this service is started.  If not,
27        // we don't want to allow it to run.
28        if (mAm.mStartedUsers.get(r.userId) == null) {
29            bringDownServiceLocked(r);
30            return msg;
31        }
32
33        // Service is now being launched, its package can't be stopped.
34        try {
35            AppGlobals.getPackageManager().setPackageStoppedState(
36                    r.packageName, false, r.userId);
37        } catch (RemoteException e) {
38        } catch (IllegalArgumentException e) {
39        }
40
41        final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
42        final String procName = r.processName;
43        ProcessRecord app;
44
45        if (!isolated) {
46            app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
47            if (app != null && app.thread != null) {
48                try {
49                    app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
50                    realStartServiceLocked(r, app, execInFg);
51                    return null;
52                } catch (TransactionTooLargeException e) {
53                    throw e;
54                } catch (RemoteException e) {
55                    Slog.w(TAG, "Exception when starting service " + r.shortName, e);
56                }
57            }
58        } else {
59            app = r.isolatedProc;
60        }
61
62        // Not running -- get it started, and enqueue this service record
63        // to be executed when the app comes up.
64        if (app == null) {
65            if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
66                    "service", r.name, false, isolated, false)) == null) {
67                bringDownServiceLocked(r);
68                return msg;
69            }
70            if (isolated) {
71                r.isolatedProc = app;
72            }
73        }
74
75        if (!mPendingServices.contains(r)) {
76            mPendingServices.add(r);
77        }
78
79        if (r.delayedStop) {
80            // Oh and hey we've already been asked to stop!
81            r.delayedStop = false;
82            if (r.startRequested) {
83                stopServiceLocked(r);
84            }
85        }
86
87        return null;
88    }
JAVA

bringUpServiceLocked方法内先判断ServiceRecord的变量appthread变量是否为null,也就是检查service对应的进程ProcessRecordApplicationThread对象是否存在,若存在,则直接执行serviceonStartCommand方法。

若不存在,则将service从重启和延时启动队列中移开,因为它正在启动中了,最后再确保拥有该service的用户已经启动了。

接着 ActivityManagerService 根据进程名procNameuid调用getProcessRecordLocked方法查看对应的进程ProcessRecord是否存在。

  • 若存在,则调用realStartServiceLocked方法。
  • 若不存在,则调用startProcessLocked方法,先启动进程。

ActivityManagerService 通过startProcessLocked方法启动一个新的进程,在分析Launcher启动 Activity 组件时已经了解过了。

ActivityManagerService 创建一个新的进程,而一个新进程的入口就是ActivityThread类的main方法。在ActivityThread内会创建一个ActivityThread对象和一个ApplicationThread对象,而在main方法内又会调用ActivityThreadattach方法,用来向 ActivityManagerService 发送一个 类型为 ATTACH_APPLICATION_TRANSACTION的进程间通信,把ApplicationThread对象传递给 ActivityManagerService,以便能够 ActivityManagerService 可以和新进程进行 Binder 进程间通信。

ActivityManagerService 响应类型为ATTACH_APPLICATION_TRANSACTION的进程间通信,执行attachApplication方法,进而执行attachApplicationLocked方法。

attachApplicationLocked方法内,首先会进行 Binder 跨进程调用,执行 ApplicationThreadbindApplication方法,然后再依次调度应用的ActivityServiceBroadcast组件。

其中,调度Service组件的代码如下:

 1    // Find any services that should be running in this process...
 2        if (!badApp) {
 3            try {
 4	            // mServices 的类型为 ActivityServices
 5                didSomething |= mServices.attachApplicationLocked(app, processName);
 6            } catch (Exception e) {
 7                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
 8                badApp = true;
 9            }
10        }
JAVA

ActivityServices 类的 attachApplicationLocked() 方法

 1    boolean attachApplicationLocked(ProcessRecord proc, String processName)
 2            throws RemoteException {
 3        boolean didSomething = false;
 4        // Collect any services that are waiting for this process to come up.
 5        if (mPendingServices.size() > 0) {
 6            ServiceRecord sr = null;
 7            try {
 8                for (int i=0; i<mPendingServices.size(); i++) {
 9                    sr = mPendingServices.get(i);
10                    if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid
11                            || !processName.equals(sr.processName))) {
12                        continue;
13                    }
14                    mPendingServices.remove(i);
15                    i--;
16                    proc.addPackage(sr.appInfo.packageName, sr.appInfo.versionCode,
17                            mAm.mProcessStats);
18                    realStartServiceLocked(sr, proc, sr.createdFromFg);
19                    didSomething = true;
20                    if (!isServiceNeeded(sr, false, false)) {// 不需要的服务就丢弃
21                        bringDownServiceLocked(sr);
22                    }
23                }
24            } catch (RemoteException e) {
25                throw e;
26            }
27        }
28        // Also, if there are any services that are waiting to restart and
29        // would run in this process, now is a good time to start them.  It would
30        // be weird to bring up the process but arbitrarily not let the services
31        // run at this point just because their restart time hasn't come up.
32        if (mRestartingServices.size() > 0) {
33            ServiceRecord sr;
34            for (int i=0; i<mRestartingServices.size(); i++) {
35                sr = mRestartingServices.get(i);
36                if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid
37                        || !processName.equals(sr.processName))) {
38                    continue;
39                }
40                mAm.mHandler.removeCallbacks(sr.restarter);
41                mAm.mHandler.post(sr.restarter);
42            }
43        }
44        return didSomething;
45    }
JAVA

attachApplicationLocked方法内启动mPendingServices队列中的服务和mRestartingServices中的服务。

真正启动服务的方法就是realStartServiceLocked

ActivityServices 类的 realStartServiceLocked() 方法

 1    private final void realStartServiceLocked(ServiceRecord r,
 2            ProcessRecord app, boolean execInFg) throws RemoteException {
 3        if (app.thread == null) {
 4            throw new RemoteException();
 5        }
 6        r.app = app;
 7        r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
 8
 9        final boolean newService = app.services.add(r);
10        // 发送一个延时消息 SERVICE_TIMEOUT_MSG,Service 若没有启动超时,则回告诉 AMS 取消该消息
11        bumpServiceExecutingLocked(r, execInFg, "create");
12        mAm.updateLruProcessLocked(app, false, null);
13        mAm.updateOomAdjLocked();
14
15        boolean created = false;
16        try {
17            if (LOG_SERVICE_START_STOP) {
18                String nameTerm;
19                int lastPeriod = r.shortName.lastIndexOf('.');
20                nameTerm = lastPeriod >= 0 ? r.shortName.substring(lastPeriod) : r.shortName;
21                EventLogTags.writeAmCreateService(
22                        r.userId, System.identityHashCode(r), nameTerm, r.app.uid, r.app.pid);
23            }
24            synchronized (r.stats.getBatteryStats()) {
25                r.stats.startLaunchedLocked();
26            }
27            mAm.ensurePackageDexOpt(r.serviceInfo.packageName);
28            app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
29            // 进入 Service 的 onCreate 
30            app.thread.scheduleCreateService(r, r.serviceInfo,
31                    mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
32                    app.repProcState);
33            r.postNotification();
34            created = true;
35        } catch (DeadObjectException e) {
36            Slog.w(TAG, "Application dead when creating service " + r);
37            mAm.appDiedLocked(app); // 创建服务时,应用挂了
38            throw e;
39        } finally {
40            if (!created) {
41                // Keep the executeNesting count accurate.
42                final boolean inDestroying = mDestroyingServices.contains(r);
43                serviceDoneExecutingLocked(r, inDestroying, inDestroying);
44
45                // Cleanup.
46                if (newService) {
47                    app.services.remove(r);
48                    r.app = null;
49                }
50
51                // Retry.
52                if (!inDestroying) {
53                    scheduleServiceRestartLocked(r, false);
54                }
55            }
56        }
57
58        requestServiceBindingsLocked(r, execInFg);
59        updateServiceClientActivitiesLocked(app, null, true);
60
61        // If the service is in the started state, and there are no
62        // pending arguments, then fake up one so its onStartCommand() will
63        // be called.
64        if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
65            r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
66                    null, null));
67        }
68		// 进入 Service 的 onStartCommand 
69        sendServiceArgsLocked(r, execInFg, true);
70
71        if (r.delayed) {
72            getServiceMap(r.userId).mDelayedStartList.remove(r);
73            r.delayed = false;
74        }
75
76        if (r.delayedStop) {
77            // Oh and hey we've already been asked to stop!
78            r.delayedStop = false;
79            if (r.startRequested) {
80                stopServiceLocked(r);
81            }
82        }
83    }
JAVA

realStartServiceLocked方法内,首先会通过bumpServiceExecutingLocked方法,然后再调用scheduleServiceTimeoutLocked方法,向 ActivityManagerService 的 MainHandler类型的 mHandler 发送一个消息 SERVICE_TIMEOUT_MSG。若 Service 在启动过程中没有及时向 ActivityManagerService 返回消息,把SERVICE_TIMEOUT_MSG消息给取消掉,那么则认为 Service 启动超时了。

标记完了时间后,就通过scheduleCreateService方法来启动 Service ,让 Service 进去onCreate状态。

新创建的进程把自己的 Binder 本地对象 ApplicationThread 传递给了 ActivityManagerService ,ActivityManagerService 就通过它来与新进程通信了,scheduleCreateService方法向 Binder 驱动发送了一个类型为 SCHEDULE_CREATE_SERVICE_TRANSACTION的消息,而在 ApplicationThread响应了该消息。

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

ApplicationThread 的 scheduleCreateService方法向 ActivityThread 的主线程 mH发送了消息CREATE_SERVICE。ActivityThread 最终响应该消息。

ActivityThread 类的 handleCreateService() 方法

 1 private void handleCreateService(CreateServiceData data) {
 2        // If we are getting ready to gc after going to the background, well
 3        // we are back active so skip it.
 4        unscheduleGcIdler();
 5
 6        LoadedApk packageInfo = getPackageInfoNoCheck(
 7                data.info.applicationInfo, data.compatInfo);
 8        Service service = null;
 9        try {
10            java.lang.ClassLoader cl = packageInfo.getClassLoader();
11            // 通过反射创建目标服务对象
12            service = (Service) cl.loadClass(data.info.name).newInstance();
13        } catch (Exception e) {
14        }
15
16        try {
17            // 创建 ContextImpl
18            ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
19            context.setOuterContext(service);
20			// 创建 Application 对象
21            Application app = packageInfo.makeApplication(false, mInstrumentation);
22            service.attach(context, this, data.info.name, data.token, app,
23                    ActivityManagerNative.getDefault());
24            // Service 进入 onCreate 状态
25            service.onCreate();
26            mServices.put(data.token, service);
27            try {
28	            // 向 ActivityManagerService 发送消息取消 Service 启动延时消息
29                ActivityManagerNative.getDefault().serviceDoneExecuting(
30                        data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
31            } catch (RemoteException e) {
32                // nothing to do.
33            }
34        } catch (Exception e) {
35        }
36    }
JAVA

ActivityThread 类的handleCreateService主要是创建了 Service 对象,并且创建了ContextImpl对象和Application对象。同时调用了 Service 的onCreate方法。我们继承的 Service 的onCreate方法也是在这里被系统回调的。

随后向 ActivityManagerService 发送消息,取消 Service 延时启动的消息。

Service 进入 onCreate状态后,接下来该进入onStartCommand状态。

ActivityServices 类的 sendServiceArgsLocked() 方法

 1    private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
 2            boolean oomAdjusted) throws TransactionTooLargeException {
 3        final int N = r.pendingStarts.size();
 4        if (N == 0) {
 5            return;
 6        }
 7
 8        while (r.pendingStarts.size() > 0) {
 9            Exception caughtException = null;
10            ServiceRecord.StartItem si;
11            try {
12                si = r.pendingStarts.remove(0);
13                if (si.intent == null && N > 1) {
14                    // If somehow we got a dummy null intent in the middle,
15                    // then skip it.  DO NOT skip a null intent when it is
16                    // the only one in the list -- this is to support the
17                    // onStartCommand(null) case.
18                    continue;
19                }
20                si.deliveredTime = SystemClock.uptimeMillis();
21                r.deliveredStarts.add(si);
22                si.deliveryCount++;
23                if (si.neededGrants != null) {
24                    mAm.grantUriPermissionUncheckedFromIntentLocked(si.neededGrants,
25                            si.getUriPermissionsLocked());
26                }
27                // 添加延时处理,类似于 onCreate 
28                bumpServiceExecutingLocked(r, execInFg, "start");
29                if (!oomAdjusted) {
30                    oomAdjusted = true;
31                    mAm.updateOomAdjLocked(r.app);
32                }
33                int flags = 0;
34                if (si.deliveryCount > 1) {
35                    flags |= Service.START_FLAG_RETRY;
36                }
37                if (si.doneExecutingCount > 0) {
38                    flags |= Service.START_FLAG_REDELIVERY;
39                }
40	            // 跨进程 Service 进入 onStartCommand 状态
41                r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
42            } catch (TransactionTooLargeException e) {
43            } catch (RemoteException e) {
44            } catch (Exception e) {
45            }
46        }
47    }
JAVA

sendServiceArgsLocked方法内通过跨进程scheduleServiceArgs方法,向 ActivityThread 发送消息。

ActivityThread 类的 handleServiceArgs() 方法

 1    private void handleServiceArgs(ServiceArgsData data) {
 2        Service s = mServices.get(data.token);
 3        if (s != null) {
 4            try {
 5                if (data.args != null) {
 6                    data.args.setExtrasClassLoader(s.getClassLoader());
 7                    data.args.prepareToEnterProcess();
 8                }
 9                int res;
10                if (!data.taskRemoved) {
11	                // Service 进入 onStartCommand 状态
12                    res = s.onStartCommand(data.args, data.flags, data.startId);
13                } else {
14                    s.onTaskRemoved(data.args);
15                    res = Service.START_TASK_REMOVED_COMPLETE;
16                }
17                QueuedWork.waitToFinish();
18                try {
19                // 向 ActivityManagerService 发送消息取消延时
20                    ActivityManagerNative.getDefault().serviceDoneExecuting(
21                            data.token, SERVICE_DONE_EXECUTING_START, data.startId, res);
22                } catch (RemoteException e) {
23                    // nothing to do.
24                }
25                ensureJitEnabled();
26            } catch (Exception e) {
27            }
28        }
29    }
JAVA

ActivityThread 响应 Binder 驱动发送来的消息,仍然通过类型为HmH处理消息,处理消息的方法就是handleServiceArgs。在方法内,回调了 Service 的onStartCommand方法,并且向 ActivityManagerService 发送消息取消了延时操作。

至此,Service 在新进程中的启动过程就分析结束了,从调用者的startService方法,再到 ActivityManagerService 的处理,再到 Service 进程的onCreateonStartCommand方法。

参考

  1. Android 6.0 源码
  2. 《Android 系统源代码情景分析》
  3. http://gityuan.com/2016/03/06/start-service/

欢迎关注微信公众号:音视频开发进阶

Licensed under CC BY-NC-SA 4.0
粤ICP备20067247号
使用 Hugo 构建    主题 StackedJimmy 设计,Jacob 修改