基于8.0源码解析:startService 启动过程

# 基于8.0源码解析:startService 启动过程欢迎关注我的公众号:

![](http://opq81riyh.bkt.clouddn.com/qrcode_for_gh_1d2b09f3edbf_258%20%282%29.jpg)---![](http://opq81riyh.bkt.clouddn.com/startservice.png)调用startService 后会到ContextWrapper中:```java@Override public ComponentName startService(Intent service) { return mBase.startService(service); }```这个mBase就是Context,然后到ContextImpl中看一眼:```java @Override1459 public ComponentName startService(Intent service) {1460 warnIfCallingFromSystemProcess();1461 return startServiceCommon(service, false, mUser);1462 }1463```又调用了startServiceCommon```javaprivate ComponentName startServiceCommon(Intent service, boolean requireForeground,1487 UserHandle user) {1488 try {1489 validateServiceIntent(service);1490 service.prepareToLeaveProcess(this);1491 ComponentName cn = ActivityManager.getService().startService(1492 mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(1493 getContentResolver()), requireForeground,1494 getOpPackageName(), user.getIdentifier());1495 if (cn != null) {1496 if (cn.getPackageName().equals("!")) {1497 throw new SecurityException(1498 "Not allowed to start service " + service1499 + " without permission " + cn.getClassName());1500 } else if (cn.getPackageName().equals("!!")) {1501 throw new SecurityException(1502 "Unable to start service " + service1503 + ": " + cn.getClassName());1504 } else if (cn.getPackageName().equals("?")) {1505 throw new IllegalStateException(1506 "Not allowed to start service " + service + ": " + cn.getClassName());1507 }1508 }1509 return cn;1510 } catch (RemoteException e) {1511 throw e.rethrowFromSystemServer();1512 }1513 }1514```看到其中有这么一句:```java ComponentName cn = ActivityManager.getService().startService(1492 mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(1493 getContentResolver()), requireForeground,1494 getOpPackageName(), user.getIdentifier());```了解Binder机制的就会知道这会调用到ActivityManagerService中,```java@Override18125 public ComponentName startService(IApplicationThread caller, Intent service,18126 String resolvedType, boolean requireForeground, String callingPackage, int userId)18127 throws TransactionTooLargeException {18128 enforceNotIsolatedCaller("startService");18129 // Refuse possible leaked file descriptors18130 if (service != null && service.hasFileDescriptors() == true) {18131 throw new IllegalArgumentException("File descriptors passed in Intent");18132 }1813318134 if (callingPackage == null) {18135 throw new IllegalArgumentException("callingPackage cannot be null");18136 }1813718138 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,18139 "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);18140 synchronized(this) {18141 final int callingPid = Binder.getCallingPid();18142 final int callingUid = Binder.getCallingUid();18143 final long origId = Binder.clearCallingIdentity();18144 ComponentName res;18145 try {18146 res = mServices.startServiceLocked(caller, service,18147 resolvedType, callingPid, callingUid,18148 requireForeground, callingPackage, userId);18149 } finally {18150 Binder.restoreCallingIdentity(origId);18151 }18152 return res;18153 }18154 }```mServices.startServiceLocked```java ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,328 int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId)329 throws TransactionTooLargeException {330 if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "startService: " + service331 + " type=" + resolvedType + " args=" + service.getExtras());332333 final boolean callerFg;334 if (caller != null) {335 final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);336 if (callerApp == null) {337 throw new SecurityException(338 "Unable to find app for caller " + caller339 + " (pid=" + callingPid340 + ") when starting service " + service);341 }342 callerFg = callerApp.setSchedGroup != ProcessList.SCHED_GROUP_BACKGROUND;343 } else {344 callerFg = true;345 }346347 ServiceLookupResult res =348 retrieveServiceLocked(service, resolvedType, callingPackage,349 callingPid, callingUid, userId, true, callerFg, false);350 if (res == null) {351 return null;352 }353 if (res.record == null) {354 return new ComponentName("!", res.permission != null355 ? res.permission : "private to package");356 }357358 ServiceRecord r = res.record;359360 if (!mAm.mUserController.exists(r.userId)) {361 Slog.w(TAG, "Trying to start service with non-existent user! " + r.userId);362 return null;363 }364365 // If this isn't a direct-to-foreground start, check our ability to kick off an366 // arbitrary service367 if (!r.startRequested && !fgRequired) {368 // Before going further -- if this app is not allowed to start services in the369 // background, then at this point we aren't going to let it period.370 final int allowed = mAm.getAppStartModeLocked(r.appInfo.uid, r.packageName,371 r.appInfo.targetSdkVersion, callingPid, false, false);372 if (allowed != ActivityManager.APP_START_MODE_NORMAL) {373 Slog.w(TAG, "Background start not allowed: service "374 + service + " to " + r.name.flattenToShortString()375 + " from pid=" + callingPid + " uid=" + callingUid376 + " pkg=" + callingPackage);377 if (allowed == ActivityManager.APP_START_MODE_DELAYED) {378 // In this case we are silently disabling the app, to disrupt as379 // little as possible existing apps.380 return null;381 }382 // This app knows it is in the new model where this operation is not383 // allowed, so tell it what has happened.384 UidRecord uidRec = mAm.mActiveUids.get(r.appInfo.uid);385 return new ComponentName("?", "app is in background uid " + uidRec);386 }387 }388389 NeededUriGrants neededGrants = mAm.checkGrantUriPermissionFromIntentLocked(390 callingUid, r.packageName, service, service.getFlags(), null, r.userId);391392 // If permissions need a review before any of the app components can run,393 // we do not start the service and launch a review activity if the calling app394 // is in the foreground passing it a pending intent to start the service when395 // review is completed.396 if (mAm.mPermissionReviewRequired) {397 if (!requestStartTargetPermissionsReviewIfNeededLocked(r, callingPackage,398 callingUid, service, callerFg, userId)) {399 return null;400 }401 }402403 if (unscheduleServiceRestartLocked(r, callingUid, false)) {404 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "START SERVICE WHILE RESTART PENDING: " + r);405 }406 r.lastActivity = SystemClock.uptimeMillis();407 r.startRequested = true;408 r.delayedStop = false;409 r.fgRequired = fgRequired;410 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),411 service, neededGrants, callingUid));412413 final ServiceMap smap = getServiceMapLocked(r.userId);414 boolean addToStarting = false;415 if (!callerFg && !fgRequired && r.app == null416 && mAm.mUserController.hasStartedUserState(r.userId)) {417 ProcessRecord proc = mAm.getProcessRecordLocked(r.processName, r.appInfo.uid, false);418 if (proc == null || proc.curProcState > ActivityManager.PROCESS_STATE_RECEIVER) {419 // If this is not coming from a foreground caller, then we may want420 // to delay the start if there are already other background services421 // that are starting. This is to avoid process start spam when lots422 // of applications are all handling things like connectivity broadcasts.423 // We only do this for cached processes, because otherwise an application424 // can have assumptions about calling startService() for a service to run425 // in its own process, and for that process to not be killed before the426 // service is started. This is especially the case for receivers, which427 // may start a service in onReceive() to do some additional work and have428 // initialized some global state as part of that.429 if (DEBUG_DELAYED_SERVICE) Slog.v(TAG_SERVICE, "Potential start delay of "430 + r + " in " + proc);431 if (r.delayed) {432 // This service is already scheduled for a delayed start; just leave433 // it still waiting.434 if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "Continuing to delay: " + r);435 return r.name;436 }437 if (smap.mStartingBackground.size() >= mMaxStartingBackground) {438 // Something else is starting, delay!439 Slog.i(TAG_SERVICE, "Delaying start of: " + r);440 smap.mDelayedStartList.add(r);441 r.delayed = true;442 return r.name;443 }444 if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "Not delaying: " + r);445 addToStarting = true;446 } else if (proc.curProcState >= ActivityManager.PROCESS_STATE_SERVICE) {447 // We slightly loosen when we will enqueue this new service as a background448 // starting service we are waiting for, to also include processes that are449 // currently running other services or receivers.450 addToStarting = true;451 if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE,452 "Not delaying, but counting as bg: " + r);453 } else if (DEBUG_DELAYED_STARTS) {454 StringBuilder sb = new StringBuilder(128);455 sb.append("Not potential delay (state=").append(proc.curProcState)456 .append(' ').append(proc.adjType);457 String reason = proc.makeAdjReason();458 if (reason != null) {459 sb.append(' ');460 sb.append(reason);461 }462 sb.append("): ");463 sb.append(r.toString());464 Slog.v(TAG_SERVICE, sb.toString());465 }466 } else if (DEBUG_DELAYED_STARTS) {467 if (callerFg || fgRequired) {468 Slog.v(TAG_SERVICE, "Not potential delay (callerFg=" + callerFg + " uid="469 + callingUid + " pid=" + callingPid + " fgRequired=" + fgRequired + "): " + r);470 } else if (r.app != null) {471 Slog.v(TAG_SERVICE, "Not potential delay (cur app=" + r.app + "): " + r);472 } else {473 Slog.v(TAG_SERVICE,474 "Not potential delay (user " + r.userId + " not started): " + r);475 }476 }477478 ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);479 return cmp;480 }```最后调用了ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);```java ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,527 boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {528 ServiceState stracker = r.getTracker();529 if (stracker != null) {530 stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity);531 }532 r.callStart = false;533 synchronized (r.stats.getBatteryStats()) {534 r.stats.startRunningLocked();535 }536 String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);537 if (error != null) {538 return new ComponentName("!!", error);539 }540541 if (r.startRequested && addToStarting) {542 boolean first = smap.mStartingBackground.size() == 0;543 smap.mStartingBackground.add(r);544 r.startingBgTimeout = SystemClock.uptimeMillis() + mAm.mConstants.BG_START_TIMEOUT;545 if (DEBUG_DELAYED_SERVICE) {546 RuntimeException here = new RuntimeException("here");547 here.fillInStackTrace();548 Slog.v(TAG_SERVICE, "Starting background (first=" + first + "): " + r, here);549 } else if (DEBUG_DELAYED_STARTS) {550 Slog.v(TAG_SERVICE, "Starting background (first=" + first + "): " + r);551 }552 if (first) {553 smap.rescheduleDelayedStartsLocked();554 }555 } else if (callerFg || r.fgRequired) {556 smap.ensureNotStartingBackgroundLocked(r);557 }558559 return r.name;560 }```这个方法中又调用到了 String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);然后掉用到: sendServiceArgsLocked(r, execInFg, false); 进而调用到: realStartServiceLocked(r, app, execInFg);```javaprivate final void realStartServiceLocked(ServiceRecord r,2190 ProcessRecord app, boolean execInFg) throws RemoteException {2191 if (app.thread == null) {2192 throw new RemoteException();2193 }2194 if (DEBUG_MU)2195 Slog.v(TAG_MU, "realStartServiceLocked, ServiceRecord.uid = " + r.appInfo.uid2196 + ", ProcessRecord.uid = " + app.uid);2197 r.app = app;2198 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();21992200 final boolean newService = app.services.add(r);2201 bumpServiceExecutingLocked(r, execInFg, "create");2202 mAm.updateLruProcessLocked(app, false, null);2203 updateServiceForegroundLocked(r.app, /* oomAdj= */ false);2204 mAm.updateOomAdjLocked();22052206 boolean created = false;2207 try {2208 if (LOG_SERVICE_START_STOP) {2209 String nameTerm;2210 int lastPeriod = r.shortName.lastIndexOf('.');2211 nameTerm = lastPeriod >= 0 ? r.shortName.substring(lastPeriod) : r.shortName;2212 EventLogTags.writeAmCreateService(2213 r.userId, System.identityHashCode(r), nameTerm, r.app.uid, r.app.pid);2214 }2215 synchronized (r.stats.getBatteryStats()) {2216 r.stats.startLaunchedLocked();2217 }2218 mAm.notifyPackageUse(r.serviceInfo.packageName,2219 PackageManager.NOTIFY_PACKAGE_USE_SERVICE);2220 app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);2221 app.thread.scheduleCreateService(r, r.serviceInfo,2222 mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),2223 app.repProcState);2224 r.postNotification();2225 created = true;2226 } catch (DeadObjectException e) {2227 Slog.w(TAG, "Application dead when creating service " + r);2228 mAm.appDiedLocked(app);2229 throw e;2230 } finally {2231 if (!created) {2232 // Keep the executeNesting count accurate.2233 final boolean inDestroying = mDestroyingServices.contains(r);2234 serviceDoneExecutingLocked(r, inDestroying, inDestroying);22352236 // Cleanup.2237 if (newService) {2238 app.services.remove(r);2239 r.app = null;2240 }22412242 // Retry.2243 if (!inDestroying) {2244 scheduleServiceRestartLocked(r, false);2245 }2246 }2247 }22482249 if (r.whitelistManager) {2250 app.whitelistManager = true;2251 }22522253 requestServiceBindingsLocked(r, execInFg);22542255 updateServiceClientActivitiesLocked(app, null, true);22562257 // If the service is in the started state, and there are no2258 // pending arguments, then fake up one so its onStartCommand() will2259 // be called.2260 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {2261 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),2262 null, null, 0));2263 }22642265 sendServiceArgsLocked(r, execInFg, true);22662267 if (r.delayed) {2268 if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "REM FR DELAY LIST (new proc): " + r);2269 getServiceMapLocked(r.userId).mDelayedStartList.remove(r);2270 r.delayed = false;2271 }22722273 if (r.delayedStop) {2274 // Oh and hey we've already been asked to stop!2275 r.delayedStop = false;2276 if (r.startRequested) {2277 if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE,2278 "Applying delayed stop (from start): " + r);2279 stopServiceLocked(r);2280 }2281 }2282 }```app.thread.scheduleCreateService,这个thread就是IApplicationThread,就是ActivityThread对象,于是我们回到ActivityThread中:```javapublic 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); }```我们去到H中找到对应的handleMessage处理CREATE_SERVICE的方法:```javacase 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:```javaprivate 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); 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, ActivityManagerNative.getDefault()); service.onCreate(); mServices.put(data.token, service); try { ActivityManagerNative.getDefault().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 = (Service) cl.loadClass(data.info.name).newInstance();用反射的方式创建了service对象;然后ContextImpl context = ContextImpl.createAppContext(this, packageInfo);又创建了context对象;然后用service.attach将context对象进行参数设置;然后就调用了service.onCreate();这就是Service的启动过程。在刚刚realStartServiceLocked方法中:调用了 app.thread.scheduleCreateService方法后又调用了: sendServiceArgsLocked(r, execInFg, true);```java private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,2285 boolean oomAdjusted) throws TransactionTooLargeException {2286 final int N = r.pendingStarts.size();2287 if (N == 0) {2288 return;2289 }22902291 ArrayListargs = new ArrayList<>();22922293 while (r.pendingStarts.size() > 0) {2294 ServiceRecord.StartItem si = r.pendingStarts.remove(0);2295 if (DEBUG_SERVICE) {2296 Slog.v(TAG_SERVICE, "Sending arguments to: "2297 + r + " " + r.intent + " args=" + si.intent);2298 }2299 if (si.intent == null && N > 1) {2300 // If somehow we got a dummy null intent in the middle,2301 // then skip it. DO NOT skip a null intent when it is2302 // the only one in the list -- this is to support the2303 // onStartCommand(null) case.2304 continue;2305 }2306 si.deliveredTime = SystemClock.uptimeMillis();2307 r.deliveredStarts.add(si);2308 si.deliveryCount++;2309 if (si.neededGrants != null) {2310 mAm.grantUriPermissionUncheckedFromIntentLocked(si.neededGrants,2311 si.getUriPermissionsLocked());2312 }2313 mAm.grantEphemeralAccessLocked(r.userId, si.intent,2314 r.appInfo.uid, UserHandle.getAppId(si.callingId));2315 bumpServiceExecutingLocked(r, execInFg, "start");2316 if (!oomAdjusted) {2317 oomAdjusted = true;2318 mAm.updateOomAdjLocked(r.app, true);2319 }2320 if (r.fgRequired && !r.fgWaiting) {2321 if (!r.isForeground) {2322 if (DEBUG_BACKGROUND_CHECK) {2323 Slog.i(TAG, "Launched service must call startForeground() within timeout: " + r);2324 }2325 scheduleServiceForegroundTransitionTimeoutLocked(r);2326 } else {2327 if (DEBUG_BACKGROUND_CHECK) {2328 Slog.i(TAG, "Service already foreground; no new timeout: " + r);2329 }2330 r.fgRequired = false;2331 }2332 }2333 int flags = 0;2334 if (si.deliveryCount > 1) {2335 flags |= Service.START_FLAG_RETRY;2336 }2337 if (si.doneExecutingCount > 0) {2338 flags |= Service.START_FLAG_REDELIVERY;2339 }2340 args.add(new ServiceStartArgs(si.taskRemoved, si.id, flags, si.intent));2341 }23422343 ParceledListSlice slice = new ParceledListSlice<>(args);

2344        slice.setInlineCountLimit(4);

2345        Exception caughtException = null;

2346        try {

2347            r.app.thread.scheduleServiceArgs(r, slice);

2348        } catch (TransactionTooLargeException e) {

2349            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Transaction too large for " + args.size()

2350                    + " args, first: " + args.get(0).args);

2351            Slog.w(TAG, "Failed delivering service starts", e);

2352            caughtException = e;

2353        } catch (RemoteException e) {

2354            // Remote process gone...  we'll let the normal cleanup take care of this.

2355            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Crashed while sending args: " + r);

2356            Slog.w(TAG, "Failed delivering service starts", e);

2357            caughtException = e;

2358        } catch (Exception e) {

2359            Slog.w(TAG, "Unexpected exception", e);

2360            caughtException = e;

2361        }

2362

2363        if (caughtException != null) {

2364            // Keep nesting count correct

2365            final boolean inDestroying = mDestroyingServices.contains(r);

2366            for (int i = 0; i < args.size(); i++) {

2367                serviceDoneExecutingLocked(r, inDestroying, inDestroying);

2368            }

2369            if (caughtException instanceof TransactionTooLargeException) {

2370                throw (TransactionTooLargeException)caughtException;

2371            }

2372        }

2373    }

```

看到有这么一句r.app.thread.scheduleServiceArgs(r, slice);

于是回到ActivityThread中:

```java

public final void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId,

            int flags ,Intent args) {

            ServiceArgsData s = new ServiceArgsData();

            s.token = token;

            s.taskRemoved = taskRemoved;

            s.startId = startId;

            s.flags = flags;

            s.args = args;

            sendMessage(H.SERVICE_ARGS, s);

        }

```

还是去H中找对应的处理case:

```java

case SERVICE_ARGS:

                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceStart: " + String.valueOf(msg.obj)));

                    handleServiceArgs((ServiceArgsData)msg.obj);

                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

                    break;

```

接着去看handleServiceArgs:

```java

private void handleServiceArgs(ServiceArgsData data) {

        Service s = mServices.get(data.token);

        if (s != null) {

            try {

                if (data.args != null) {

                    data.args.setExtrasClassLoader(s.getClassLoader());

                    data.args.prepareToEnterProcess();

                }

                int res;

                if (!data.taskRemoved) {

                    res = s.onStartCommand(data.args, data.flags, data.startId);

                } else {

                    s.onTaskRemoved(data.args);

                    res = Service.START_TASK_REMOVED_COMPLETE;

                }

                QueuedWork.waitToFinish();

                try {

                    ActivityManagerNative.getDefault().serviceDoneExecuting(

                            data.token, SERVICE_DONE_EXECUTING_START, data.startId, res);

                } catch (RemoteException e) {

                    throw e.rethrowFromSystemServer();

                }

                ensureJitEnabled();

            } catch (Exception e) {

                if (!mInstrumentation.onException(s, e)) {

                    throw new RuntimeException(

                            "Unable to start service " + s

                            + " with " + data.args + ": " + e.toString(), e);

                }

            }

        }

    }

```

s.onStartCommand中s就是上面创建的service对象。那么onStartCommand方法就是在这里调用的。至此service启动过程完毕。下面画图看下这个流程:

![](http://opq81riyh.bkt.clouddn.com/startservice.png)

你可能感兴趣的:(基于8.0源码解析:startService 启动过程)