- 概述
- startService()启动过程
- 1.应用端启动Service
- 2.ContextWrapper.startService()
- 3.ContextImpl.startService()
- 4.ContextImpl.startServiceCommon()
- 5.AMS.startService()
- 6.AS.startServiceLocked(9 args)
- 7.AS.startServiceLocked(11 args)
- 8.AS.startServiceInnerLocked()
- 9.AS.bringUpServiceLocked()
- 10.AS.realStartServiceLocked()
- <执行AT.scheduleCreateService()分支>
- 11.AT.handleCreateService()
- <AT.scheduleCreateService()分支完成>
- <执行AS.sendServiceArgsLocked()分支>
- 12.AT.handleServiceArgs()
- <AS.sendServiceArgsLocked()分支完成>
概述
bindService()启动过程
(1) 发起端进程
Context.bindService() ->
ContextWrapper.bindService() ->
ContextImpl.bindService() ->
ContextImpl.bindServiceCommon()
之后调用bindIsolatedService()方法与AMS交互。
(1) AMS与服务端处理部分
AMS.bindIsolatedService() ->
ActiveServices.bindServiceLocked()
之后分为3种情况:
- 如果Service已启动,则只回调onBind()
AS.requestServiceBindingLocked() ->
ActivityThread.ApplicationThread.scheduleBindService(){sendMessage(H.BIND_SERVICE, s)} ->
ActivityThread.handleBindService() ->
MyService.onBind()
- 如果进程已存在但Service未启动,需要回调onCreate()和onBind()
AS.retrieveServiceLocked() ->
AS.bringUpServiceLocked() ->
AS.realStartServiceLocked() ->
AT.scheduleCreateService(){ sendMessage(H.CREATE_SERVICE, s); } ->
AT.handleCreateService()->
MyService.onCreate()
执行完onCreate(),函数返回到AS.realStartServiceLocked()中,继续执行:
AS.requestServiceBindingsLocked() ->
ActivityThread.ApplicationThread.scheduleBindService(){sendMessage(H.BIND_SERVICE, s)} ->
ActivityThread.handleBindService() ->
MyService.onBind()
在AT.handleBindService()中还会执行publishService(),其作用是创建客户端到服务端的连接。
try {
if (!data.rebind) {
IBinder binder = s.onBind(data.intent);
ActivityManager.getService().publishService(
data.token, data.intent, binder);
} else {
s.onRebind(data.intent);
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
}
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
- 如果进程不存在
ServiceRecord.retrieveAppBindingLocked() ->
ActiveServices.bringUpServiceLocked() ->
AMS.startProcessLocked() //将ServiceRecord对象添加到mPendingServices中
//...
//启动进程流程,之后进入APP的main()
ActivityThread.main() ->
ActivityThread.attach() ->
AMS.attachApplication() ->
AS.attachApplicationLocked() -> //处理之前的mPendingServices
AS.realStartServiceLocked()
之后的逻辑就和“进程已存在但Service未启动”中的AS.realStartServiceLocked()后的处理流程一样了。
startForegroundService()启动过程
(1) Service生命周期
开启前台Service:
serviceIntent = new Intent(this, MyService.class);
startForegroundService(serviceIntent);
APP端:
ContextWrapper.startForegroundService() ->
ContextImpl.startForegroundService() ->
ContextImpl.startServiceCommon(intent,requireForeground=true,user)
System端:
在AS.bringUpServiceLocked()中,如果进程存在,则继续向下;如果不存在,则启动进程然后继续向下执行realStartServiceLocked()。在该函数中会调用sendServiceArgsLocked()发送前台通知延时消息。
AMS.startService() ->
AS.startServiceLocked(9 args) ->
AS.startServiceLocked(10 args) ->
AS.startServiceInnerLocked() ->
AS.bringUpServiceLocked() ->
判断进程是否启动 ->
AS.realStartServiceLocked()
在realStartServiceLocked()执行以下流程并回调到APP端:
AT.handleCreateService() // 执行onCreate
AS.sendServiceArgsLocked() // 执行onStartCommand
前台通知启动过程
在自定义MyService的onStartCommand()中还需要执行startForeground(int id, notification),其流程如下:
startForeground(int id, notification)
Service.startForeground(int id, notification)
AMS.setServiceForeground()
AS.setServiceForegroundLocked()
AS.setServiceForegroundInnerLocked()
ServiceRecord.postNotification()
NMS.enqueueNotification()
NMS.enqueueNotificationInternal(8 args)
NMS.enqueueNotificationInternal(9 args)
实际上在AS.realStartServiceLocked()中也会调用ServiceRecord.postNotification(),但如果是首次启动Service,则会因为isForeground=false及foregroundNoti = null而退出。
public void postNotification() {
if (isForeground && foregroundNoti != null && app != null) {
//...
}
}
Android 12+通知延迟10s显示
Android 12+系统会等待10s才显示跟前台Service有关的通知(为短期运行的FGS提供优化体验),以下情况可以豁免(即立刻显示通知):
- The service is associated with a notification that includes action buttons.
- The service has a foregroundServiceType of mediaPlayback, mediaProjection, or phoneCall.
- The service provides a use case related to phone calls, navigation, or media playback, as defined in the notification’s category attribute.
- Service在配置通知时调用setForegroundServiceBehavior(Notification.FOREGROUND_SERVICE_IMMEDIATE)
在Notification.shouldShowForegroundImmediately()中判断是否立刻显示通知,调用流程如下:
NMS.enqueueNotification()
NMS.enqueueNotificationInternal(8 args)
NMS.enqueueNotificationInternal(9 args)
AMS.applyForegroundServiceNotification()
AS.applyForegroundServiceNotificationLocked()
AS.shouldShowFgsNotificationLocked()
startService()启动过程
Base on: Android 11
1.应用端启动Service
(1) 自定义的Service
public class MyService extends Service {
public MyService() {
}
@Override
public IBinder onBind(Intent intent) {
Log.d("MyService", "onBind executed");
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
}
@Override
public void onDestroy() {
super.onDestroy();
}
}
(2) 启动Service
public class MainActivity extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent startIntent = new Intent(this, MyService.class);
startService(startIntent); // 启动服务
}
}
(3) 调用ContextWrapper.startService()
public class Activity extends ContextThemeWrapper
implements LayoutInflater.Factory2,
Window.Callback, KeyEvent.Callback,
OnCreateContextMenuListener, ComponentCallbacks2,
Window.OnWindowDismissedCallback,
AutofillManager.AutofillClient, ContentCaptureManager.ContentCaptureClient {......}
public class ContextThemeWrapper extends ContextWrapper {......}
2.ContextWrapper.startService()
在ContextWrapper.startService()中调用mBase.startService(Intent service),此处的mBase 实际上是一个ContextImpl对象,ContextWrapper在此处用了装饰者模式。
public class ContextWrapper extends Context {
Context mBase;
public ContextWrapper(Context base) {
mBase = base;
}
@Override
public ComponentName startService(Intent service) {
return mBase.startService(service);
}
}
3.ContextImpl.startService()
class ContextImpl extends Context {
public ComponentName startService(Intent service) {
warnIfCallingFromSystemProcess();
return startServiceCommon(service, false, mUser);
}
/**
* Logs a warning if the system process directly called a method such as
* {@link #startService(Intent)} instead of {@link #startServiceAsUser(Intent, UserHandle)}.
* The "AsUser" variants allow us to properly enforce the user's restrictions.
*/
private void warnIfCallingFromSystemProcess() {
if (Process.myUid() == Process.SYSTEM_UID) {
Slog.w(TAG, "Calling a method in the system process without a qualified user: "
+ Debug.getCallers(5));
}
}
}
如果进程system_server直接调用ContextImpl.startService()而不是startServiceAsUser(),则会打印警告信息和前5行堆栈。
4.ContextImpl.startServiceCommon()
private ComponentName startServiceCommon(Intent service, boolean requireForeground,
UserHandle user) {
try {
validateServiceIntent(service);
service.prepareToLeaveProcess(this);
ComponentName cn = ActivityManager.getService().startService(
mMainThread.getApplicationThread(), service,
service.resolveTypeIfNeeded(getContentResolver()), requireForeground,
getOpPackageName(), getAttributionTag(), user.getIdentifier());
if (cn != null) {
if (cn.getPackageName().equals("!")) {
throw new SecurityException(
"Not allowed to start service " + service
+ " without permission " + cn.getClassName());
} else if (cn.getPackageName().equals("!!")) {
throw new SecurityException(
"Unable to start service " + service
+ ": " + cn.getClassName());
} else if (cn.getPackageName().equals("?")) {
throw new IllegalStateException(
"Not allowed to start service " + service + ": " + cn.getClassName());
}
}
return cn;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
validateServiceIntent(service)用于检验service,若service为空则throw异常。
然后通过ActivityManager.getService()进行Binder调用,获取服务端AMS的引用。
ActivityManager.java中的Binder调用过程如下:
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
5.AMS.startService()
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, boolean requireForeground, String callingPackage,
String callingFeatureId, int userId)
throws TransactionTooLargeException {
enforceNotIsolatedCaller("startService");
// 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;
}
}
方法参数说明:
caller:IApplicationThread类型,复杂处理
service:Intent类型,包含需要运行的service信息
resolvedType:String类型
callingPackage: String类型,调用该方法的package
userId: int类型,用户的id
6.AS.startServiceLocked(9 args)
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);
}
7.AS.startServiceLocked(11 args)
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 {...}
8.AS.startServiceInnerLocked()
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
ServiceState stracker = r.getTracker();
if (stracker != null) {
stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity);
}
r.callStart = false;
FrameworkStatsLog.write(FrameworkStatsLog.SERVICE_STATE_CHANGED, r.appInfo.uid,
r.name.getPackageName(), r.name.getClassName(),
FrameworkStatsLog.SERVICE_STATE_CHANGED__STATE__START);
synchronized (r.stats.getBatteryStats()) {
r.stats.startRunningLocked();
}
String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
if (error != null) {
return new ComponentName("!!", error);
}
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;
}
9.AS.bringUpServiceLocked()
代码较多
这里分为两种情况:
进程已存在->AS.realStartServiceLocked()
if (app != null && app.thread != null) {
try {
app.addPackage(r.appInfo.packageName, r.appInfo.longVersionCode, mAm.mProcessStats);
realStartServiceLocked(r, app, execInFg);
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.
}
进程不存在->AMS.startProcessLocked()
当目标进程不存在,则先执行startProcessLocked创建进程,经过层层调用最后会调用到AMS.attachApplicationLocked, 然后再执行realStartServiceLocked()。
if (app == null && !permissionsReviewRequired) {
// TODO (chriswailes): Change the Zygote policy flags based on if the launch-for-service
// was initiated from a notification tap or not.
if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
hostingRecord, ZYGOTE_POLICY_FLAG_EMPTY, false, isolated, false)) == 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);
return msg;
}
if (isolated) {
r.isolatedProc = app;
}
}
(1) AMS端
ActiveServices.bringUpServiceLocked() ->
ActivityManagerService.startProcessLocked() ->
ProcessList.startProcessLocked() ->
ProcessList.startProcessLocked() ->
ProcessList.startProcessLocked() ->
ProcessList.startProcessLocked()
(2) Zygote流程
在Zygote进程中创建新进程,然后调用到ActivityThread.main()。
(3) 新进程
ActivityThread.main() ->
ActivityThread.attach() ->
AMS.attachApplication()
(4) AMS端
IActivityManager$Stub.onTransact() ->
ActivityManagerService.attachApplication() ->
ActivityManagerService.attachApplicationLocked() ->
ActiveServices.attachApplicationLocked() ->
ActiveServices.realStartServiceLocked()
10.AS.realStartServiceLocked()
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
if (app.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);
r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
final boolean newService = app.startService(r);
bumpServiceExecutingLocked(r, execInFg, "create");
//......
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, r.app.pid);
}
FrameworkStatsLog.write(FrameworkStatsLog.SERVICE_LAUNCH_REPORTED, r.appInfo.uid,
r.name.getPackageName(), r.name.getClassName());
synchronized (r.stats.getBatteryStats()) {
r.stats.startLaunchedLocked();
}
mAm.notifyPackageUse(r.serviceInfo.packageName,
PackageManager.NOTIFY_PACKAGE_USE_SERVICE);
app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo),
app.getReportedProcState());
r.postNotification();
created = true;
} catch (DeadObjectException e) {
//......
} finally {
if (!created) {
// Keep the executeNesting count accurate.
final boolean inDestroying = mDestroyingServices.contains(r);
serviceDoneExecutingLocked(r, inDestroying, inDestroying);
// ......
}
// ......
}
}
//......
sendServiceArgsLocked(r, execInFg, true);
//......
}
(1) 通过bumpServiceExecutingLocked发送延迟消息
AS.bumpServiceExecutingLocked()->AS.scheduleServiceTimeoutLocked()
(2) 通过scheduleCreateService()进入onCreate
通过app.thread.scheduleCreateService()执行APP端的调用,其中app.thread是一个IApplicationThread对象,其服务端的实现位于ActivityThread.java:
private class ApplicationThread extends IApplicationThread.Stub {......}
(3) 通过serviceDoneExecutingLocked移除延迟消息
(4) 通过sendServiceArgsLocked()进入onStartCommand
AS.bumpServiceExecutingLocked()-发送延时消息
private final void bumpServiceExecutingLocked(ServiceRecord r, boolean fg, String why) {
//......
if (r.executeNesting == 0) {
//......
if (r.app != null) {
r.app.executingServices.add(r);
r.app.execServicesFg |= fg;
if (timeoutNeeded && r.app.executingServices.size() == 1) {
scheduleServiceTimeoutLocked(r.app);
}
}
} else if (r.app != null && fg && !r.app.execServicesFg) {
r.app.execServicesFg = true;
if (timeoutNeeded) {
scheduleServiceTimeoutLocked(r.app);
}
}
//......
}
bumpServiceExecutingLocked()调用AS.scheduleServiceTimeoutLocked(r.app),该函数会发送一个延迟处理的消息SERVICE_TIMEOUT_MSG。在方法AT.scheduleCreateService()执行完成,也就是onCreate回调执行完成之后,便会remove掉该消息。但是如果没能在延时时间之内remove该消息,则会进入执行service timeout流程。
void scheduleServiceTimeoutLocked(ProcessRecord proc) {
if (proc.executingServices.size() == 0 || proc.thread == null) {
return;
}
Message msg = mAm.mHandler.obtainMessage(
ActivityManagerService.SERVICE_TIMEOUT_MSG);
msg.obj = proc;
mAm.mHandler.sendMessageDelayed(msg,
proc.execServicesFg ? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT);
}
AT.scheduleCreateService()->onCreate()
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);
}
然后执行线程间的消息传递:
class H extends Handler {
//......
@UnsupportedAppUsage
public static final int RECEIVER = 113;
@UnsupportedAppUsage
public static final int CREATE_SERVICE = 114;
@UnsupportedAppUsage
public static final int SERVICE_ARGS = 115;
//.......
String codeToString(int code) {
if (DEBUG_MESSAGES) {
switch (code) {
case BIND_APPLICATION: return "BIND_APPLICATION";
case EXIT_APPLICATION: return "EXIT_APPLICATION";
case RECEIVER: return "RECEIVER";
case CREATE_SERVICE: return "CREATE_SERVICE";
case SERVICE_ARGS: return "SERVICE_ARGS";
case STOP_SERVICE: return "STOP_SERVICE";
//......
}
}
return Integer.toString(code);
}
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
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;
//......
}
AS.serviceDoneExecutingLocked(3 arg)->移除延时消息
boolean created表示是否成功创建Service。
初始时,created = false,在执行try{……}中的代码时,若发生异常,则表示service创建失败(即不会执行created = true),于是在catch中报出DeadObjectException错误并打印相关日志后,然后在finally代码块中执行serviceDoneExecutingLocked()用于移除之前AS.bumpServiceExecutingLocked()发送的延时消息。
boolean created = false;
try {
//......
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo),
app.getReportedProcState());
r.postNotification();
created = true;
} catch (DeadObjectException e) {
//......
} finally {
if (!created) {
// Keep the executeNesting count accurate.
final boolean inDestroying = mDestroyingServices.contains(r);
serviceDoneExecutingLocked(r, inDestroying, inDestroying);
// Cleanup.
if (newService) {
app.stopService(r);
r.setProcess(null);
}
// Retry.
if (!inDestroying) {
scheduleServiceRestartLocked(r, false);
}
}
}
注:在AT.scheduleCreateService()->onCreate()的调用栈中,也会执行一次scheduleServiceRestartLocked(),此时是service创建成功时的情况。
AS.sendServiceArgsLocked()->onStartCommand()
private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
boolean oomAdjusted) throws TransactionTooLargeException {
//......
bumpServiceExecutingLocked(r, execInFg, "start");
if (!oomAdjusted) {
oomAdjusted = true;
mAm.updateOomAdjLocked(r.app, true, OomAdjuster.OOM_ADJ_REASON_START_SERVICE);
}
//......
ParceledListSlice<ServiceStartArgs> slice = new ParceledListSlice<>(args);
slice.setInlineCountLimit(4);
Exception caughtException = null;
try {
r.app.thread.scheduleServiceArgs(r, slice);
} catch (TransactionTooLargeException e) {
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Transaction too large for " + args.size()
+ " args, first: " + args.get(0).args);
Slog.w(TAG, "Failed delivering service starts", e);
caughtException = e;
} catch (RemoteException e) {
// Remote process gone... we'll let the normal cleanup take care of this.
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Crashed while sending args: " + r);
Slog.w(TAG, "Failed delivering service starts", e);
caughtException = e;
} catch (Exception e) {
Slog.w(TAG, "Unexpected exception", e);
caughtException = e;
}
if (caughtException != null) {
// Keep nesting count correct
final boolean inDestroying = mDestroyingServices.contains(r);
for (int i = 0; i < args.size(); i++) {
serviceDoneExecutingLocked(r, inDestroying, inDestroying);
}
if (caughtException instanceof TransactionTooLargeException) {
throw (TransactionTooLargeException)caughtException;
}
}
}
此函数中的执行代码类似于AS.realStartServiceLocked()。
(1) 通过bumpServiceExecutingLocked发送延迟消息
AS.bumpServiceExecutingLocked()->AS.scheduleServiceTimeoutLocked()
(2) 通过scheduleServiceArgs()进入onStartCommand
通过app.thread.scheduleServiceArgs()执行APP端的调用,其中app.thread是一个IApplicationThread对象,其服务端的实现位于ActivityThread.java:
private class ApplicationThread extends IApplicationThread.Stub {
//......
public final void scheduleServiceArgs(IBinder token, ParceledListSlice args) {
List<ServiceStartArgs> list = args.getList();
for (int i = 0; i < list.size(); i++) {
ServiceStartArgs ssa = list.get(i);
ServiceArgsData s = new ServiceArgsData();
s.token = token;
s.taskRemoved = ssa.taskRemoved;
s.startId = ssa.startId;
s.flags = ssa.flags;
s.args = ssa.args;
sendMessage(H.SERVICE_ARGS, s);
}
//......
}
}
向ActivityThread发送SERVICE_ARGS消息,然后执行AT.handleServiceArgs():
(3) 通过serviceDoneExecutingLocked移除延迟消息
if (caughtException != null) {
// Keep nesting count correct
final boolean inDestroying = mDestroyingServices.contains(r);
for (int i = 0; i < args.size(); i++) {
serviceDoneExecutingLocked(r, inDestroying, inDestroying);
}
if (caughtException instanceof TransactionTooLargeException) {
throw (TransactionTooLargeException)caughtException;
}
}
若发生异常,则抛出异常并移除超时消息。
<执行AT.scheduleCreateService()分支>
11.AT.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 {
if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
Application app = packageInfo.makeApplication(false, mInstrumentation);
java.lang.ClassLoader cl = packageInfo.getClassLoader();
service = packageInfo.getAppFactory()
.instantiateService(cl, data.info.name, data.intent);
// Service resources must be initialized with the same loaders as the application
// context.
context.getResources().addLoaders(
app.getResources().getLoaders().toArray(new ResourcesLoader[0]));
context.setOuterContext(service);
service.attach(context, this, data.info.name, data.token, app,
ActivityManager.getService());
service.onCreate();
mServices.put(data.token, service);
try {
ActivityManager.getService().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.onCreate()
到此进入了APP端的Service生命周期,并最终调用service.onCreate()方法,此处的service是继承于Service类的自定义service,通过service = packageInfo.getAppFactory().instantiateService()赋值。
自定义服务都是继承于Service,并覆写该方式,调用service.onCreate()方法,最终调用到Service.onCreate()。
AMS.serviceDoneExecuting()
由AT.handleCreateService()中的:
try {
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
调用而来。
AMS.serviceDoneExecuting()的具体代码:
final ActiveServices mServices;
public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
synchronized(this) {
if (!(token instanceof ServiceRecord)) {
Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
throw new IllegalArgumentException("Invalid service token");
}
mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
}
}
然后调用4参数的AS.serviceDoneExecutingLocked():
void serviceDoneExecutingLocked(ServiceRecord r, int type, int startId, int res) {
boolean inDestroying = mDestroyingServices.contains(r);
if (r != null) {
//......
final long origId = Binder.clearCallingIdentity();
serviceDoneExecutingLocked(r, inDestroying, inDestroying);
Binder.restoreCallingIdentity(origId);
} else {
Slog.w(TAG, "Done executing unknown service from pid "
+ Binder.getCallingPid());
}
}
然后调用3参数的AS.serviceDoneExecutingLocked():
private void serviceDoneExecutingLocked(ServiceRecord r, boolean inDestroying,
boolean finishing) {
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "<<< DONE EXECUTING " + r
+ ": nesting=" + r.executeNesting
+ ", inDestroying=" + inDestroying + ", app=" + r.app);
else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG_SERVICE_EXECUTING,
"<<< DONE EXECUTING " + r.shortInstanceName);
r.executeNesting--;
if (r.executeNesting <= 0) {
if (r.app != null) {
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
"Nesting at 0 of " + r.shortInstanceName);
r.app.execServicesFg = false;
r.app.executingServices.remove(r);
if (r.app.executingServices.size() == 0) {
if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG_SERVICE_EXECUTING,
"No more executingServices of " + r.shortInstanceName);
mAm.mHandler.removeMessages(ActivityManagerService.SERVICE_TIMEOUT_MSG, r.app);
} else if (r.executeFg) {
// Need to re-evaluate whether the app still needs to be in the foreground.
for (int i=r.app.executingServices.size()-1; i>=0; i--) {
if (r.app.executingServices.valueAt(i).executeFg) {
r.app.execServicesFg = true;
break;
}
}
}
if (inDestroying) {
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
"doneExecuting remove destroying " + r);
mDestroyingServices.remove(r);
r.bindings.clear();
}
mAm.updateOomAdjLocked(r.app, true, OomAdjuster.OOM_ADJ_REASON_UNBIND_SERVICE);
}
r.executeFg = false;
if (r.tracker != null) {
final int memFactor = mAm.mProcessStats.getMemFactorLocked();
final long now = SystemClock.uptimeMillis();
r.tracker.setExecuting(false, memFactor, now);
r.tracker.setForeground(false, memFactor, now);
if (finishing) {
r.tracker.clearCurrentOwner(r, false);
r.tracker = null;
}
}
if (finishing) {
if (r.app != null && !r.app.isPersistent()) {
r.app.stopService(r);
r.app.updateBoundClientUids();
if (r.whitelistManager) {
updateWhitelistManagerLocked(r.app);
}
}
r.setProcess(null);
}
}
}
若service的create一切正常,无超时发生,则在此步通过 mAm.mHandler.removeMessages()移除service启动超时消息SERVICE_TIMEOUT_MSG。通常超时原因是因为service的onCreate()方法执行时间过长。
<AT.scheduleCreateService()分支完成>
<执行AS.sendServiceArgsLocked()分支>
12.AT.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 {
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_START, data.startId, res);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
} catch (Exception e) {
if (!mInstrumentation.onException(s, e)) {
throw new RuntimeException(
"Unable to start service " + s
+ " with " + data.args + ": " + e.toString(), e);
}
}
}
}
同onCreate一样,此处执行service在APP端的生命周期。
Service.onStartCommand()
public @StartResult int onStartCommand(Intent intent, @StartArgFlags int flags, int startId) {
onStart(intent, startId);
return mStartCompatibility ? START_STICKY_COMPATIBILITY : START_STICKY;
}
public void onStart(Intent intent, int startId) {
}
onStartCommand()调用onStart()。
AMS.serviceDoneExecuting()
调用栈同AT.handleCreateService()中一样。
若service的onStartCommand的执行一切正常,无超时发生,则在此步通过 mAm.mHandler.removeMessages()移除service启动超时消息SERVICE_TIMEOUT_MSG。通常超时原因是因为service的onStartCommand()方法执行时间过长。