startService启动过程-Android12
Posted xhBruce
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了startService启动过程-Android12相关的知识,希望对你有一定的参考价值。
startService启动过程-android12
android12-release
时序图
1. startService启动简要流程
查看上图,startService启动简要流程如下,主要关注ActiveServices.java
:启动前台服务、Service超时检查、APP进程未启动情况
Activity.startService -> ContextImpl.startService -> ContextImpl.startServiceCommon -> AMS.startService -> ActiveServices.startServiceLocked -> ActiveServices.startServiceInnerLocked -> ActiveServices.bringUpServiceLocked -> ActiveServices.realStartServiceLocked -> ApplicationThread.scheduleCreateService -> ActivityThread.handleCreateService -> Service.onCreate()
2. 启动前台服务
在 Android 8.0(API 级别 26)及更高版本中,系统会限制应用在后台运行时可以执行的操作。
以 Android 12 或更高版本为目标平台的应用无法在后台运行时启动前台服务,少数特殊情况除外。如果应用尝试在后台运行时启动前台服务,则会引发异常(少数特殊情况除外)。
2.1 Android 8.0:Service 后台定义
系统可以区分前台和后台应用。 (用于 Service 限制目的的后台定义
与内存管理使用的定义
不同;一个应用按照内存管理的定义可能处于后台,但按照能够启动 Service 的定义又处于前台。)如果满足以下任意条件,应用将被视为处于前台:
- 具有可见 Activity(不管该 Activity 已启动还是已暂停)。
- 具有前台 Service。
- 另一个前台应用已关联到该应用(不管是通过绑定到其中一个 Service,还是通过使用其中一个内容提供程序)。 例如,如果另一个应用绑定到该应用的 Service,那么该应用处于前台:1. IME,2. 壁纸 Service,3. 通知侦听器,4. 语音或文本 Service
如果以上条件均不满足,应用将被视为处于后台。
2.1.1 startForegroundService启动前台服务
在 Android 8.0 之前,创建前台 Service 的方式通常是先创建一个后台 Service,然后将该 Service 推到前台。 Android 8.0 有一项复杂功能:系统不允许后台应用创建后台 Service。 因此,Android 8.0 引入了一种全新的方法,即 startForegroundService()
,以在前台启动新 Service。 在系统创建 Service 后,应用有5秒的时间来调用该 Service 的 startForeground()
方法以显示新 Service 的用户可见通知。 如果应用在此时间限制内未调用 startForeground()
,则系统将停止此 Service 并声明此应用为 ANR。
2.2 Android 12 :Service应用无法在后台运行时启动前台服务
除少数特殊情况外,面向Android 12(API级别31)或更高版本的应用程序在后台运行时无法启动前台服务(startForegroundService()
也不允许)。如果应用程序在后台运行时尝试启动前台服务,而前台服务不满足其中一种例外情况,则系统会抛出ForegroundServiceStartNotAllowedException。
当您的应用在后台运行时,请考虑使用 WorkManager 来计划和启动加急工作。如需完成用户请求的紧急操作,请按照精确的闹钟启动前台服务。
frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
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 (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);
if (CompatChanges.isChangeEnabled(FGS_START_EXCEPTION_CHANGE_ID, callingUid))
throw new ForegroundServiceStartNotAllowedException(msg);
return null;
// ... ...
// 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;
// ... ...
return startServiceInnerLocked(r, service, callingUid, callingPid, fgRequired, callerFg,
allowBackgroundActivityStarts, backgroundActivityStartsToken);
3. Service超时检查
可以查看 ANR service TimeOut 超时判断
ContextImpl.startService -> ContextImpl.startServiceCommon -> AMS.startService -> ActiveServices.startServiceLocked -> ActiveServices.startServiceInnerLocked -> ActiveServices.bringUpServiceLocked -> ActiveServices.realStartServiceLocked -> ActiveServices.bumpServiceExecutingLocked -> ActiveServices.scheduleServiceTimeoutLocked
不同电在于
Build.HW_TIMEOUT_MULTIPLIER
(ro.hw_timeout_multiplier默认值是1)属性值可以设置SERVICE_TIMEOUT
4. APP进程未启动情况
需要mAm.startProcessLocked()
启动进程,和 AMS:startActivity桌面启动应用 启动进程差不多,在ActivityManagerService.attachApplicationLocked
最终调用ActiveServices.realStartServiceLocked
以上是关于startService启动过程-Android12的主要内容,如果未能解决你的问题,请参考以下文章