您的位置:首页 > 移动开发 > Android开发

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

2018-01-24 16:01 525 查看


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

调用startService 后会到ContextWrapper中:

@Override
public ComponentName startService(Intent service) {
return mBase.startService(service);
}


这个mBase就是Context,然后到ContextImpl中看一眼:

@Override
1459    public ComponentName startService(Intent service) {
1460        warnIfCallingFromSystemProcess();
1461        return startServiceCommon(service, false, mUser);
1462    }
1463


又调用了startServiceCommon

private 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 " + service
1499                            + " without permission " + cn.getClassName());
1500                } else if (cn.getPackageName().equals("!!")) {
1501                    throw new SecurityException(
1502                            "Unable to start service " + service
1503                            + ": " + 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


看到其中有这么一句:

ComponentName cn = ActivityManager.getService().startService(
1492                mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
1493                            getContentResolver()), requireForeground,
1494                            getOpPackageName(), user.getIdentifier());


了解Binder机制的就会知道这会调用到ActivityManagerService中,

@Override
18125    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 descriptors
18130        if (service != null && service.hasFileDescriptors() == true) {
18131            throw new IllegalArgumentException("File descriptors passed in Intent");
18132        }
18133
18134        if (callingPackage == null) {
18135            throw new IllegalArgumentException("callingPackage cannot be null");
18136        }
18137
18138        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

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: " + service
331                + " type=" + resolvedType + " args=" + service.getExtras());
332
333        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 " + caller
339                        + " (pid=" + callingPid
340                        + ") when starting service " + service);
341            }
342            callerFg = callerApp.setSchedGroup != ProcessList.SCHED_GROUP_BACKGROUND;
343        } else {
344            callerFg = true;
345        }
346
347        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 != null
355                    ? res.permission : "private to package");
356        }
357
358        ServiceRecord r = res.record;
359
360        if (!mAm.mUserController.exists(r.userId)) {
361            Slog.w(TAG, "Trying to start service with non-existent user! " + r.userId);
362            return null;
363        }
364
365        // If this isn't a direct-to-foreground start, check our ability to kick off an
366        // arbitrary service
367        if (!r.startRequested && !fgRequired) {
368            // Before going further -- if this app is not allowed to start services in the
369            // 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=" + callingUid
376                        + " pkg=" + callingPackage);
377                if (allowed == ActivityManager.APP_START_MODE_DELAYED) {
378                    // In this case we are silently disabling the app, to disrupt as
379                    // little as possible existing apps.
380                    return null;
381                }
382                // This app knows it is in the new model where this operation is not
383                // 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        }
388
389        NeededUriGrants neededGrants = mAm.checkGrantUriPermissionFromIntentLocked(
390                callingUid, r.packageName, service, service.getFlags(), null, r.userId);
391
392        // 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 app
394        // is in the foreground passing it a pending intent to start the service when
395        // review is completed.
396        if (mAm.mPermissionReviewRequired) {
397            if (!requestStartTargetPermissionsReviewIfNeededLocked(r, callingPackage,
398                    callingUid, service, callerFg, userId)) {
399                return null;
400            }
401        }
402
403        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));
412
413        final ServiceMap smap = getServiceMapLocked(r.userId);
414        boolean addToStarting = false;
415        if (!callerFg && !fgRequired && r.app == null
416                && 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 want
420                // to delay the start if there are already other background services
421                // that are starting.  This is to avoid process start spam when lots
422                // of applications are all handling things like connectivity broadcasts.
423                // We only do this for cached processes, because otherwise an application
424                // can have assumptions about calling startService() for a service to run
425                // in its own process, and for that process to not be killed before the
426                // service is started.  This is especially the case for receivers, which
427                // may start a service in onReceive() to do some additional work and have
428                // 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 leave
433                    // 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 background
448                // starting service we are waiting for, to also include processes that are
449                // 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        }
477
478        ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
479        return cmp;
480    }


最后调用了ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);

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        }
540
541        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        }
558
559        return r.name;
560    }


这个方法中又调用到了 String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);

然后掉用到:

sendServiceArgsLocked(r, execInFg, false);

进而调用到:

realStartServiceLocked(r, app, execInFg);

private 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.uid
2196                    + ", ProcessRecord.uid = " + app.uid);
2197        r.app = app;
2198        r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
2199
2200        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();
2205
2206        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);
2235
2236                // Cleanup.
2237                if (newService) {
2238                    app.services.remove(r);
2239                    r.app = null;
2240                }
2241
2242                // Retry.
2243                if (!inDestroying) {
2244                    scheduleServiceRestartLocked(r, false);
2245                }
2246            }
2247        }
2248
2249        if (r.whitelistManager) {
2250            app.whitelistManager = true;
2251        }
2252
2253        requestServiceBindingsLocked(r, execInFg);
2254
2255        updateServiceClientActivitiesLocked(app, null, true);
2256
2257        // If the service is in the started state, and there are no
2258        // pending arguments, then fake up one so its onStartCommand() will
2259        // 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        }
2264
2265        sendServiceArgsLocked(r, execInFg, true);
2266
2267        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        }
2272
2273        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中:

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);
}


我们去到H中找到对应的handleMessage处理CREATE_SERVICE的方法:

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:

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);

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);

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        }
2290
2291        ArrayList<ServiceStartArgs> args = new ArrayList<>();
2292
2293        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 is
2302                // the only one in the list -- this is to support the
2303                // 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        }
2342
2343        ParceledListSlice<ServiceStartArgs> 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中:

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:

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:

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启动过程完毕。下面画图看下这个流程:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android