ActivityManagerService的startService方法用于启动一个Service,流程如下:
代码如下:
//frameworks/base/service/core/java/com/android/server/am/ActivityManagerService.java
public class ActivityManagerService extends IActivityManager.Stub
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback, ActivityManagerGlobalLock {
final ActiveServices mServices;
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, boolean requireForeground, String callingPackage,
String callingFeatureId, int userId)
throws TransactionTooLargeException {
enforceNotIsolatedCaller("startService");
enforceAllowedToStartOrBindServiceIfSdkSandbox(service);
// Refuse possible leaked file descriptors
if (service != null && service.hasFileDescriptors() == true) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}
if (callingPackage == null) {
throw new IllegalArgumentException("callingPackage cannot be null");
}
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
"*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
synchronized(this) {
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
ComponentName res;
try {
res = mServices.startServiceLocked(caller, service,
resolvedType, callingPid, callingUid,
requireForeground, callingPackage, callingFeatureId, userId);
} finally {
Binder.restoreCallingIdentity(origId);
}
return res;
}
}
}
ActiveServices startServiceLocked
调用mServices(ActiveServices)的startServiceLocked方法:
//frameworks/base/service/core/java/com/android/server/am/ActiveServices.java
public final class ActiveServices {
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
int callingPid, int callingUid, boolean fgRequired, String callingPackage,
@Nullable String callingFeatureId, final int userId)
throws TransactionTooLargeException {
return startServiceLocked(caller, service, resolvedType, callingPid, callingUid, fgRequired,
callingPackage, callingFeatureId, userId, false, null);
}
}
调用startServiceLocked方法:
//frameworks/base/service/core/java/com/android/server/am/ActiveServices.java
public final class ActiveServices {
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
int callingPid, int callingUid, boolean fgRequired,
String callingPackage, @Nullable String callingFeatureId, final int userId,
boolean allowBackgroundActivityStarts, @Nullable IBinder backgroundActivityStartsToken)
throws TransactionTooLargeException {
if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "startService: " + service
+ " type=" + resolvedType + " args=" + service.getExtras());
final boolean callerFg;
if (caller != null) {
final ProcessRecord callerApp = mAm.getRecordForAppLOSP(caller);
if (callerApp == null) {
throw new SecurityException(
"Unable to find app for caller " + caller
+ " (pid=" + callingPid
+ ") when starting service " + service);
}
callerFg = callerApp.mState.getSetSchedGroup() != ProcessList.SCHED_GROUP_BACKGROUND;
} else {
callerFg = true;
}
//调用 retrieveServiceLocked 查找根据第三方进程传递进来的 Intent 所对应的服务,即系统中是否存在符合 intent 携带消息的 Service
ServiceLookupResult res =
retrieveServiceLocked(service, null, resolvedType, callingPackage,
callingPid, callingUid, userId, true, callerFg, false, false);
if (res == null) {
return null;
}
if (res.record == null) {
return new ComponentName("!", res.permission != null
? res.permission : "private to package");
}
ServiceRecord r = res.record;
setFgsRestrictionLocked(callingPackage, callingPid, callingUid, service, r, userId,
allowBackgroundActivityStarts);
if (!mAm.mUserController.exists(r.userId)) {
Slog.w(TAG, "Trying to start service with non-existent user! " + r.userId);
return null;
}
// If we're starting indirectly (e.g. from PendingIntent), figure out whether
// we're launching into an app in a background state. This keys off of the same
// idleness state tracking as e.g. O+ background service start policy.
final boolean bgLaunch = !mAm.isUidActiveLOSP(r.appInfo.uid);
// If the app has strict background restrictions, we treat any bg service
// start analogously to the legacy-app forced-restrictions case, regardless
// of its target SDK version.
boolean forcedStandby = false;
if (bgLaunch && appRestrictedAnyInBackground(r.appInfo.uid, r.packageName)) {
if (DEBUG_FOREGROUND_SERVICE) {
Slog.d(TAG, "Forcing bg-only service start only for " + r.shortInstanceName
+ " : bgLaunch=" + bgLaunch + " callerFg=" + callerFg);
}
forcedStandby = true;
}
if (fgRequired) {
logFgsBackgroundStart(r);
if (r.mAllowStartForeground == REASON_DENIED && isBgFgsRestrictionEnabled(r)) {
String msg = "startForegroundService() not allowed due to "
+ "mAllowStartForeground false: service "
+ r.shortInstanceName;
Slog.w(TAG, msg);
showFgsBgRestrictedNotificationLocked(r);
logFGSStateChangeLocked(r,
FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__DENIED,
0, FGS_STOP_REASON_UNKNOWN);
if (CompatChanges.isChangeEnabled(FGS_START_EXCEPTION_CHANGE_ID, callingUid)) {
throw new ForegroundServiceStartNotAllowedException(msg);
}
return null;
}
}
// If this is a direct-to-foreground start, make sure it is allowed as per the app op.
boolean forceSilentAbort = false;
if (fgRequired) {
final int mode = mAm.getAppOpsManager().checkOpNoThrow(
AppOpsManager.OP_START_FOREGROUND, r.appInfo.uid, r.packageName);
switch (mode) {
case AppOpsManager.MODE_ALLOWED:
case AppOpsManager.MODE_DEFAULT:
// All okay.
break;
case AppOpsManager.MODE_IGNORED:
// Not allowed, fall back to normal start service, failing siliently
// if background check restricts that.
Slog.w(TAG, "startForegroundService not allowed due to app op: service "
+ service + " to " + r.shortInstanceName
+ " from pid=" + callingPid + " uid=" + callingUid
+ " pkg=" + callingPackage);
fgRequired = false;
forceSilentAbort = true;
break;
default:
return new ComponentName("!!", "foreground not allowed as per app op");
}
}
// If this isn't a direct-to-foreground start, check our ability to kick off an
// arbitrary service
if (forcedStandby || (!r.startRequested && !fgRequired)) {
// Before going further -- if this app is not allowed to start services in the
// background, then at this point we aren't going to let it period.
final int allowed = mAm.getAppStartModeLOSP(r.appInfo.uid, r.packageName,
r.appInfo.targetSdkVersion, callingPid, false, false, forcedStandby);
if (allowed != ActivityManager.APP_START_MODE_NORMAL) {
Slog.w(TAG, "Background start not allowed: service "
+ service + " to " + r.shortInstanceName
+ " from pid=" + callingPid + " uid=" + callingUid
+ " pkg=" + callingPackage + " startFg?=" + fgRequired);
if (allowed == ActivityManager.APP_START_MODE_DELAYED || forceSilentAbort) {
// In this case we are silently disabling the app, to disrupt as
// little as possible existing apps.
return null;
}
if (forcedStandby) {
// This is an O+ app, but we might be here because the user has placed
// it under strict background restrictions. Don't punish the app if it's
// trying to do the right thing but we're denying it for that reason.
if (fgRequired) {
if (DEBUG_BACKGROUND_CHECK) {
Slog.v(TAG, "Silently dropping foreground service launch due to FAS");
}
return null;
}
}
// This app knows it is in the new model where this operation is not
// allowed, so tell it what has happened.
UidRecord uidRec = mAm.mProcessList.getUidRecordLOSP(r.appInfo.uid);
return new ComponentName("?", "app is in background uid " + uidRec);
}
}
// At this point we've applied allowed-to-start policy based on whether this was
// an ordinary startService() or a startForegroundService(). Now, only require that
// the app follow through on the startForegroundService() -> startForeground()
// contract if it actually targets O+.
if (r.appInfo.targetSdkVersion < Build.VERSION_CODES.O && fgRequired) {
if (DEBUG_BACKGROUND_CHECK || DEBUG_FOREGROUND_SERVICE) {
Slog.i(TAG, "startForegroundService() but host targets "
+ r.appInfo.targetSdkVersion + " - not requiring startForeground()");
}
fgRequired = false;
}
// The package could be frozen (meaning it's doing surgery), defer the actual
// start until the package is unfrozen.
if (deferServiceBringupIfFrozenLocked(r, service, callingPackage, callingFeatureId,
callingUid, callingPid, fgRequired, callerFg, userId, allowBackgroundActivityStarts,
backgroundActivityStartsToken, false, null)) {
return null;
}
// If permissions need a review before any of the app components can run,
// we do not start the service and launch a review activity if the calling app
// is in the foreground passing it a pending intent to start the service when
// review is completed.
// XXX This is not dealing with fgRequired!
if (!requestStartTargetPermissionsReviewIfNeededLocked(r, callingPackage, callingFeatureId,
callingUid, service, callerFg, userId, false, null)) {
return null;
}
// If what the client try to start/connect was an alias, then we need to return the
// alias component name to the client, not the "target" component name, which is
// what realResult contains.
final ComponentName realResult =
startServiceInnerLocked(r, service, callingUid, callingPid, fgRequired, callerFg,
allowBackgroundActivityStarts, backgroundActivityStartsToken);
if (res.aliasComponent != null
&& !realResult.getPackageName().startsWith("!")
&& !realResult.getPackageName().startsWith("?")) {
return res.aliasComponent;
} else {
return realResult;
}
}
}
调用startServiceInnerLocked方法:
//frameworks/base/service/core/java/com/android/server/am/ActiveServices.java
public final class ActiveServices {
private ComponentName startServiceInnerLocked(ServiceRecord r, Intent service,
int callingUid, int callingPid, boolean fgRequired, boolean callerFg,
boolean allowBackgroundActivityStarts, @Nullable IBinder backgroundActivityStartsToken)
throws TransactionTooLargeException {
NeededUriGrants neededGrants = mAm.mUgmInternal.checkGrantUriPermissionFromIntent(
service, callingUid, r.packageName, r.userId);
if (unscheduleServiceRestartLocked(r, callingUid, false)) {
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "START SERVICE WHILE RESTART PENDING: " + r);
}
final boolean wasStartRequested = r.startRequested;
r.lastActivity = SystemClock.uptimeMillis();
r.startRequested = true;
r.delayedStop = false;
r.fgRequired = fgRequired;
r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
service, neededGrants, callingUid));
if (fgRequired) {
// We are now effectively running a foreground service.
synchronized (mAm.mProcessStats.mLock) {
final ServiceState stracker = r.getTracker();
if (stracker != null) {
stracker.setForeground(true, mAm.mProcessStats.getMemFactorLocked(),
SystemClock.uptimeMillis()); // Use current time, not lastActivity.
}
}
mAm.mAppOpsService.startOperation(AppOpsManager.getToken(mAm.mAppOpsService),
AppOpsManager.OP_START_FOREGROUND, r.appInfo.uid, r.packageName, null,
true, false, null, false, AppOpsManager.ATTRIBUTION_FLAGS_NONE,
AppOpsManager.ATTRIBUTION_CHAIN_ID_NONE);
}
final ServiceMap smap = getServiceMapLocked(r.userId);
boolean addToStarting = false;
if (!callerFg && !fgRequired && r.app == null
&& mAm.mUserController.hasStartedUserState(r.userId)) {
ProcessRecord proc = mAm.getProcessRecordLocked(r.processName, r.appInfo.uid);
if (proc == null || proc.mState.getCurProcState() > PROCESS_STATE_RECEIVER) {
// If this is not coming from a foreground caller, then we may want
// to delay the start if there are already other background services
// that are starting. This is to avoid process start spam when lots
// of applications are all handling things like connectivity broadcasts.
// We only do this for cached processes, because otherwise an application
// can have assumptions about calling startService() for a service to run
// in its own process, and for that process to not be killed before the
// service is started. This is especially the case for receivers, which
// may start a service in onReceive() to do some additional work and have
// initialized some global state as part of that.
if (DEBUG_DELAYED_SERVICE) Slog.v(TAG_SERVICE, "Potential start delay of "
+ r + " in " + proc);
if (r.delayed) {
// This service is already scheduled for a delayed start; just leave
// it still waiting.
if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "Continuing to delay: " + r);
return r.name;
}
if (smap.mStartingBackground.size() >= mMaxStartingBackground) {
// Something else is starting, delay!
Slog.i(TAG_SERVICE, "Delaying start of: " + r);
smap.mDelayedStartList.add(r);
r.delayed = true;
return r.name;
}
if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "Not delaying: " + r);
addToStarting = true;
} else if (proc.mState.getCurProcState() >= ActivityManager.PROCESS_STATE_SERVICE) {
// We slightly loosen when we will enqueue this new service as a background
// starting service we are waiting for, to also include processes that are
// currently running other services or receivers.
addToStarting = true;
if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE,
"Not delaying, but counting as bg: " + r);
} else if (DEBUG_DELAYED_STARTS) {
StringBuilder sb = new StringBuilder(128);
sb.append("Not potential delay (state=").append(proc.mState.getCurProcState())
.append(' ').append(proc.mState.getAdjType());
String reason = proc.mState.makeAdjReason();
if (reason != null) {
sb.append(' ');
sb.append(reason);
}
sb.append("): ");
sb.append(r.toString());
Slog.v(TAG_SERVICE, sb.toString());
}
} else if (DEBUG_DELAYED_STARTS) {
if (callerFg || fgRequired) {
Slog.v(TAG_SERVICE, "Not potential delay (callerFg=" + callerFg + " uid="
+ callingUid + " pid=" + callingPid + " fgRequired=" + fgRequired + "): " + r);
} else if (r.app != null) {
Slog.v(TAG_SERVICE, "Not potential delay (cur app=" + r.app + "): " + r);
} else {
Slog.v(TAG_SERVICE,
"Not potential delay (user " + r.userId + " not started): " + r);
}
}
if (allowBackgroundActivityStarts) {
r.allowBgActivityStartsOnServiceStart(backgroundActivityStartsToken);
}
ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting,
callingUid, wasStartRequested);
return cmp;
}
}
调用startServiceInnerLocked方法:
//frameworks/base/service/core/java/com/android/server/am/ActiveServices.java
public final class ActiveServices {
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
boolean callerFg, boolean addToStarting, int callingUid, boolean wasStartRequested)
throws TransactionTooLargeException {
synchronized (mAm.mProcessStats.mLock) {
final ServiceState stracker = r.getTracker();
if (stracker != null) {
stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(),
SystemClock.uptimeMillis()); // Use current time, not lastActivity.
}
}
r.callStart = false;
final int uid = r.appInfo.uid;
final String packageName = r.name.getPackageName();
final String serviceName = r.name.getClassName();
FrameworkStatsLog.write(FrameworkStatsLog.SERVICE_STATE_CHANGED, uid, packageName,
serviceName, FrameworkStatsLog.SERVICE_STATE_CHANGED__STATE__START);
mAm.mBatteryStatsService.noteServiceStartRunning(uid, packageName, serviceName);
// 关键点:拉起服务.
String error = bringUpServiceLocked(r, service.getFlags(), callerFg,
false /* whileRestarting */,
false /* permissionsReviewRequired */,
false /* packageFrozen */,
true /* enqueueOomAdj */);
/* Will be a no-op if nothing pending */
mAm.updateOomAdjPendingTargetsLocked(OomAdjuster.OOM_ADJ_REASON_START_SERVICE);
if (error != null) {
return new ComponentName("!!", error);
}
FrameworkStatsLog.write(SERVICE_REQUEST_EVENT_REPORTED, uid, callingUid,
ActivityManagerService.getShortAction(service.getAction()),
SERVICE_REQUEST_EVENT_REPORTED__REQUEST_TYPE__START, false,
r.app == null || r.app.getThread() == null
? SERVICE_REQUEST_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_COLD
: (wasStartRequested || !r.getConnections().isEmpty()
? SERVICE_REQUEST_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_HOT
: SERVICE_REQUEST_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_WARM));
if (r.startRequested && addToStarting) {
boolean first = smap.mStartingBackground.size() == 0;
smap.mStartingBackground.add(r);
r.startingBgTimeout = SystemClock.uptimeMillis() + mAm.mConstants.BG_START_TIMEOUT;
if (DEBUG_DELAYED_SERVICE) {
RuntimeException here = new RuntimeException("here");
here.fillInStackTrace();
Slog.v(TAG_SERVICE, "Starting background (first=" + first + "): " + r, here);
} else if (DEBUG_DELAYED_STARTS) {
Slog.v(TAG_SERVICE, "Starting background (first=" + first + "): " + r);
}
if (first) {
smap.rescheduleDelayedStartsLocked();
}
} else if (callerFg || r.fgRequired) {
smap.ensureNotStartingBackgroundLocked(r);
}
return r.name;
}
}
调用bringUpServiceLocked方法:
//frameworks/base/service/core/java/com/android/server/am/ActiveServices.java
public final class ActiveServices {
final ActivityManagerService mAm;
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
boolean whileRestarting, boolean permissionsReviewRequired, boolean packageFrozen,
boolean enqueueOomAdj)
throws TransactionTooLargeException {
if (r.app != null && r.app.getThread() != null) {
// 调用 service.onStartCommand()
sendServiceArgsLocked(r, execInFg, false);
return null;
}
if (!whileRestarting && mRestartingServices.contains(r)) {
// If waiting for a restart, then do nothing.
return null;
}
if (DEBUG_SERVICE) {
Slog.v(TAG_SERVICE, "Bringing up " + r + " " + r.intent + " fg=" + r.fgRequired);
}
// We are now bringing the service up, so no longer in the
// restarting state.
if (mRestartingServices.remove(r)) {
clearRestartingIfNeededLocked(r);
}
// Make sure this service is no longer considered delayed, we are starting it now.
if (r.delayed) {
if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "REM FR DELAY LIST (bring up): " + r);
getServiceMapLocked(r.userId).mDelayedStartList.remove(r);
r.delayed = false;
}
// Make sure that the user who owns this service is started. If not,
// we don't want to allow it to run.
if (!mAm.mUserController.hasStartedUserState(r.userId)) {
String msg = "Unable to launch app "
+ r.appInfo.packageName + "/"
+ r.appInfo.uid + " for service "
+ r.intent.getIntent() + ": user " + r.userId + " is stopped";
Slog.w(TAG, msg);
bringDownServiceLocked(r, enqueueOomAdj);
return msg;
}
// Report usage if binding is from a different package except for explicitly exempted
// bindings
if (!r.appInfo.packageName.equals(r.mRecentCallingPackage)
&& !r.isNotAppComponentUsage) {
mAm.mUsageStatsService.reportEvent(
r.packageName, r.userId, UsageEvents.Event.APP_COMPONENT_USED);
}
// Service is now being launched, its package can't be stopped.
try {
AppGlobals.getPackageManager().setPackageStoppedState(
r.packageName, false, r.userId);
} catch (RemoteException e) {
} catch (IllegalArgumentException e) {
Slog.w(TAG, "Failed trying to unstop package "
+ r.packageName + ": " + e);
}
final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
final String procName = r.processName;
HostingRecord hostingRecord = new HostingRecord(
HostingRecord.HOSTING_TYPE_SERVICE, r.instanceName,
r.definingPackageName, r.definingUid, r.serviceInfo.processName,
getHostingRecordTriggerType(r));
ProcessRecord app; //ProcessRecord类用于管理应用检测的进程信息和状态,ProcessRecord和进程之前是一对一的关系,每个进程都会对应一个ProcessRecord。
if (!isolated) {
app = mAm.getProcessRecordLocked(procName, r.appInfo.uid); //取得Service对应的进程记录。
if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid
+ " app=" + app);
if (app != null) {
// 如果进程已经启动
final IApplicationThread thread = app.getThread(); //获取ApplicationThread
final int pid = app.getPid();
final UidRecord uidRecord = app.getUidRecord();
if (thread != null) {
try {
app.addPackage(r.appInfo.packageName, r.appInfo.longVersionCode,
mAm.mProcessStats);
// 启动服务
realStartServiceLocked(r, app, thread, pid, uidRecord, execInFg,
enqueueOomAdj);
return null;
} catch (TransactionTooLargeException e) {
throw e;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting service " + r.shortInstanceName, e);
}
// If a dead object exception was thrown -- fall through to
// restart the application.
}
}
} else {
// If this service runs in an isolated process, then each time
// we call startProcessLocked() we will get a new isolated
// process, starting another process if we are currently waiting
// for a previous process to come up. To deal with this, we store
// in the service any current isolated process it is running in or
// waiting to have come up.
app = r.isolationHostProc;
if (WebViewZygote.isMultiprocessEnabled()
&& r.serviceInfo.packageName.equals(WebViewZygote.getPackageName())) {
hostingRecord = HostingRecord.byWebviewZygote(r.instanceName, r.definingPackageName,
r.definingUid, r.serviceInfo.processName);
}
if ((r.serviceInfo.flags & ServiceInfo.FLAG_USE_APP_ZYGOTE) != 0) {
hostingRecord = HostingRecord.byAppZygote(r.instanceName, r.definingPackageName,
r.definingUid, r.serviceInfo.processName);
}
}
// Not running -- get it started, and enqueue this service record
// to be executed when the app comes up.
if (app == null && !permissionsReviewRequired && !packageFrozen) {
//如果进程没有启动
// TODO (chriswailes): Change the Zygote policy flags based on if the launch-for-service
// was initiated from a notification tap or not.
if (r.isSdkSandbox) {
final int uid = Process.toSdkSandboxUid(r.sdkSandboxClientAppUid);
app = mAm.startSdkSandboxProcessLocked(procName, r.appInfo, true, intentFlags,
hostingRecord, ZYGOTE_POLICY_FLAG_EMPTY, uid, r.sdkSandboxClientAppPackage);
r.isolationHostProc = app;
} else {
// 启动进程
app = mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
hostingRecord, ZYGOTE_POLICY_FLAG_EMPTY, false, isolated);
}
if (app == null) {
String msg = "Unable to launch app "
+ r.appInfo.packageName + "/"
+ r.appInfo.uid + " for service "
+ r.intent.getIntent() + ": process is bad";
Slog.w(TAG, msg);
bringDownServiceLocked(r, enqueueOomAdj);
return msg;
}
if (isolated) {
r.isolationHostProc = app;
}
}
if (r.fgRequired) {
if (DEBUG_FOREGROUND_SERVICE) {
Slog.v(TAG, "Allowlisting " + UserHandle.formatUid(r.appInfo.uid)
+ " for fg-service launch");
}
mAm.tempAllowlistUidLocked(r.appInfo.uid,
mAm.mConstants.mServiceStartForegroundTimeoutMs, REASON_SERVICE_LAUNCH,
"fg-service-launch",
TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
r.mRecentCallingUid);
}
if (!mPendingServices.contains(r)) {
mPendingServices.add(r);
}
if (r.delayedStop) {
// Oh and hey we've already been asked to stop!
r.delayedStop = false;
if (r.startRequested) {
if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE,
"Applying delayed stop (in bring up): " + r);
stopServiceLocked(r, enqueueOomAdj);
}
}
return null;
}
}
上面方法的主要处理如下:
1、调用mAm(ActivityManagerService)的getProcessRecordLocked方法,向ActivityManagerService取得Service对应的进程记录。
2、如果Service对应的进程处于运行状态,调用ActiveServices的realStartServiceLocked启动服务。
3、如果Service对应的进程处于未运行状态,调用ActivityManagerService的startProcessLocked启动Service对应的进程。
下面分别进行分析:
ActivityManagerService getProcessRecordLocked
调用mAm(ActivityManagerService)的getProcessRecordLocked方法,向ActivityManagerService取得Service对应的进程记录。
//frameworks/base/service/core/java/com/android/server/am/ActivityManagerService.java
public class ActivityManagerService extends IActivityManager.Stub
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback, ActivityManagerGlobalLock {
final ProcessRecord getProcessRecordLocked(String processName, int uid) {
return mProcessList.getProcessRecordLocked(processName, uid);
}
}
ActiveServices realStartServiceLocked
调用realStartServiceLocked方法:
//frameworks/base/service/core/java/com/android/server/am/ActiveServices.java
public final class ActiveServices {
private void realStartServiceLocked(ServiceRecord r, ProcessRecord app,
IApplicationThread thread, int pid, UidRecord uidRecord, boolean execInFg,
boolean enqueueOomAdj) throws RemoteException {
if (thread == null) {
throw new RemoteException();
}
if (DEBUG_MU)
Slog.v(TAG_MU, "realStartServiceLocked, ServiceRecord.uid = " + r.appInfo.uid
+ ", ProcessRecord.uid = " + app.uid);
r.setProcess(app, thread, pid, uidRecord);
r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
final ProcessServiceRecord psr = app.mServices;
final boolean newService = psr.startService(r);
bumpServiceExecutingLocked(r, execInFg, "create", null /* oomAdjReason */); // 发送ANR 检测消息
mAm.updateLruProcessLocked(app, false, null);
updateServiceForegroundLocked(psr, /* oomAdj= */ false);
// Force an immediate oomAdjUpdate, so the client app could be in the correct process state
// before doing any service related transactions
mAm.enqueueOomAdjTargetLocked(app);
mAm.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_START_SERVICE);
boolean created = false;
try {
if (LOG_SERVICE_START_STOP) {
String nameTerm;
int lastPeriod = r.shortInstanceName.lastIndexOf('.');
nameTerm = lastPeriod >= 0 ? r.shortInstanceName.substring(lastPeriod)
: r.shortInstanceName;
EventLogTags.writeAmCreateService(
r.userId, System.identityHashCode(r), nameTerm, r.app.uid, pid);
}
final int uid = r.appInfo.uid;
final String packageName = r.name.getPackageName();
final String serviceName = r.name.getClassName();
FrameworkStatsLog.write(FrameworkStatsLog.SERVICE_LAUNCH_REPORTED, uid, packageName,
serviceName);
mAm.mBatteryStatsService.noteServiceStartLaunch(uid, packageName, serviceName);
mAm.notifyPackageUse(r.serviceInfo.packageName,
PackageManager.NOTIFY_PACKAGE_USE_SERVICE);
thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo),
app.mState.getReportedProcState());
r.postNotification();
created = true;
} catch (DeadObjectException e) {
Slog.w(TAG, "Application dead when creating service " + r);
mAm.appDiedLocked(app, "Died when creating service");
throw e;
} finally {
if (!created) {
// Keep the executeNesting count accurate.
final boolean inDestroying = mDestroyingServices.contains(r);
serviceDoneExecutingLocked(r, inDestroying, inDestroying, false);
// Cleanup.
if (newService) {
psr.stopService(r);
r.setProcess(null, null, 0, null);
}
// Retry.
if (!inDestroying) {
scheduleServiceRestartLocked(r, false);
}
}
}
if (r.allowlistManager) {
psr.mAllowlistManager = true;
}
requestServiceBindingsLocked(r, execInFg);
updateServiceClientActivitiesLocked(psr, null, true);
if (newService && created) {
psr.addBoundClientUidsOfNewService(r);
}
// If the service is in the started state, and there are no
// pending arguments, then fake up one so its onStartCommand() will
// be called.
if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
null, null, 0));
}
// 回调onStartCommand()方法
sendServiceArgsLocked(r, execInFg, true);
if (r.delayed) {
if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "REM FR DELAY LIST (new proc): " + r);
getServiceMapLocked(r.userId).mDelayedStartList.remove(r);
r.delayed = false;
}
if (r.delayedStop) {
// Oh and hey we've already been asked to stop!
r.delayedStop = false;
if (r.startRequested) {
if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE,
"Applying delayed stop (from start): " + r);
stopServiceLocked(r, enqueueOomAdj);
}
}
}
}
ApplicationThread scheduleCreateService
调用thread(IApplicationThread)的scheduleCreateService方法,IApplicationThread是一个接口,由ApplicationThread实现:
//frameworks/base/core/java/android/app/ActivityThread.java
public final class ActivityThread extends ClientTransactionHandler implements ActivityThreadInternal {
private class ApplicationThread extends IApplicationThread.Stub {
public final void scheduleCreateService(IBinder token,
ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
updateProcessState(processState, false);
CreateServiceData s = new CreateServiceData();
s.token = token;
s.info = info;
s.compatInfo = compatInfo;
sendMessage(H.CREATE_SERVICE, s); 发送CREATE_SERVICE消息
}
}
}
发送CREATE_SERVICE消息,消息会在H的handleMessage方法中处理:
//frameworks/base/core/java/android/app/ActivityThread.java
public final class ActivityThread extends ClientTransactionHandler implements ActivityThreadInternal {
class H extends Handler {
public void handleMessage(Message msg) {
switch (msg.what) {
case CREATE_SERVICE:
if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
("serviceCreate: " + String.valueOf(msg.obj)));
}
handleCreateService((CreateServiceData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
}
}
}
}
ActivityThread handleCreateService
调用ActivityThread的handleCreateService方法处理ServiceCreate请求。
Android13 ActivityThread handleCreateService流程分析-CSDN博客
ActivityManagerService startProcessLocked
如果Service对应的进程处于未运行状态,调用ActivityManagerService的startProcessLocked启动Service对应的进程:
Android13 ActivityManagerService startProcessLocked流程分析-CSDN博客