1.简介
1.1.Q
- 对比下startService和startForegroundService的区别.
- 前台服务里,如果不调用startForeground启动前台通知,服务为啥会crash,如何做到的?
1.2.A
- startService是启动一个普通的服务,startForegroundService是启动一个前台服务,必须带一个前台通知,好让用户知道有这么一个服务在运行中,服务不容易被杀死。
- 参考2.3,启动前台服务后,会给对应的服务new一个错误异常放入map里,后续读取这个异常提示用户,非必须
- 5.4.4启动前台服务的时候,会调用5.9的方法post一个30秒后处理的超时msg
- 参考6.4,启动前台通知,会移除2.3末尾添加的异常map,接着走到5.6 ,5.7里会移除上边添加的延迟30秒的msg
1.3.启动流程
-
2.2到2.3,intent的验证以及初始化,
-
完事到4.1,caller的过滤,
-
到5.1,会调用5.2的方法查找服务信息,中间一些权限检查等,
-
最后调用5.4的方法进行最终的启动,启动成功返回组件名。
-
5.4.1里更新服务状态为前台服务,调用5.4.2方法拉起服务。
-
服务超时msg的设置见5.4.4,具体逻辑见5.9,
-
msg取消见5.7(调用startForeground方法启动前台通知就会走这里)
2.ContextImpl.java
2.1.startService
public ComponentName startService(Intent service) {
warnIfCallingFromSystemProcess();
//见2.3,参数为false
return startServiceCommon(service, false, mUser);
}
2.2.startForegroundService
public ComponentName startForegroundService(Intent service) {
//见补充1
warnIfCallingFromSystemProcess();
//见2.3,参数为true
return startServiceCommon(service, true, mUser);
}
>1.warnIfCallingFromSystemProcess
就是个警告,系统进程调用会有个警告日志。就是说系统进程调用必须后边加个AsUser并传递user参数。
startServiceAsUser
startForegroundServiceAsUser
2.3.startServiceCommon
- requireForeground决定了是否是前台服务
private ComponentName startServiceCommon(Intent service, boolean requireForeground,
UserHandle user) {
try {
//验证intent是否有效,就是必须有包名或者组件名
validateServiceIntent(service);
//见3.1,intent的准备工作处理
service.prepareToLeaveProcess(this);
//见4.1 ,这里的getService返回的就是AMS
ComponentName cn = ActivityManager.getService().startService(
mMainThread.getApplicationThread(), service,
service.resolveTypeIfNeeded(getContentResolver()), requireForeground,
getOpPackageName(), getAttributionTag(), user.getIdentifier());
if (cn != null) {
//几种异常包名检查,抛出异常
}
}
//返回的组件不为空,并且请求的是前台服务
if (cn != null && requireForeground) {
//服务组件的包名和当前上下文的包名一样
if (cn.getPackageName().equals(getOpPackageName())) {
//见小节6.1,添加一个异常对象到map里,到时候有异常的话再取出来使用
//见6.4,启动前台通知以后,这个异常就被清除了
Service.setStartForegroundServiceStackTrace(cn.getClassName(),
new StackTrace("Last startServiceCommon() call for this service was "
+ "made here"));
}
}
return cn;
}
}
>1.getOpPackageName
正常就是当前上下文的包名,构造方法里创建对象的时候赋予的
public String getOpPackageName() {
return mAttributionSource.getPackageName();
}
3.Intent.java
3.1.prepareToLeaveProcess
就是对比下当前上下文和intent里的包名是否一样,不一样就说明不是一个进程
public void prepareToLeaveProcess(Context context) {
final boolean leavingPackage;
if (mComponent != null) {
//当前上下文的包名和要跳转的服务包名不一样,则返回true,一样返回false
leavingPackage = !Objects.equals(mComponent.getPackageName(), context.getPackageName());
} else if (mPackage != null) {
//包名不一样,则不是一个进程
leavingPackage = !Objects.equals(mPackage, context.getPackageName());
} else {
//没有声明组件的,则认为还在当进程
leavingPackage = true;
}
//见3.2
prepareToLeaveProcess(leavingPackage);
}
3.2.prepareToLeaveProcess
public void prepareToLeaveProcess(boolean leavingPackage) {
//见补充1,不允许fds
setAllowFds(false);
if (mSelector != null) {
mSelector.prepareToLeaveProcess(leavingPackage);
}
if (mClipData != null) {
mClipData.prepareToLeaveProcess(leavingPackage, getFlags());
}
if (mOriginalIntent != null) {
mOriginalIntent.prepareToLeaveProcess(leavingPackage);
}
if (mExtras != null && !mExtras.isParcelled()) {
final Object intent = mExtras.get(Intent.EXTRA_INTENT);
if (intent instanceof Intent) {
((Intent) intent).prepareToLeaveProcess(leavingPackage);
}
}
//..
}
>1.setAllowFds
- allowFds 为true表示允许使用文件描述符,这样可以传递大数据,否则数据大小有限制,具体参考上边的帖子
public void setAllowFds(boolean allowFds) {
if (mExtras != null) {
mExtras.setAllowFds(allowFds);
}
}
4.ActivityManagerService.java
4.1.startService
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, boolean requireForeground, String callingPackage,
String callingFeatureId, int userId)
throws TransactionTooLargeException {
//具体见补充1,就是对caller的uid进行判定
enforceNotIsolatedCaller("startService");
//caller的uid在20000到29999,需要有对应的权限
enforceAllowedToStartOrBindServiceIfSdkSandbox(service);
if (service != null && service.hasFileDescriptors() == true) {
//不允许有文件描述符
throw new IllegalArgumentException("File descriptors passed in Intent");
}
synchronized(this) {
ComponentName res;
try {
//见5.1
res = mServices.startServiceLocked(caller, service,
resolvedType, callingPid, callingUid,
requireForeground, callingPackage, callingFeatureId, userId);
return res;
}
}
>1.isIsolated
99000<=uid<=99999 或者90000<=uid<=98999
public static final boolean isIsolated(int uid) {
uid = UserHandle.getAppId(uid);
return (uid >= FIRST_ISOLATED_UID && uid <= LAST_ISOLATED_UID)
|| (uid >= FIRST_APP_ZYGOTE_ISOLATED_UID && uid <= LAST_APP_ZYGOTE_ISOLATED_UID);
}
4.2.validateAssociationAllowedLocked
- 运行在uid1下的pkg1 是否可以与 运行在uid2下的pkg2 进行交流?association
boolean validateAssociationAllowedLocked(String pkg1, int uid1, String pkg2, int uid2) {
// mAllowedAssociations集合数据读取
ensureAllowedAssociations();
if (uid1 == uid2 || UserHandle.getAppId(uid1) == SYSTEM_UID
|| UserHandle.getAppId(uid2) == SYSTEM_UID) {
//uid一样,或者有一个是系统uid
return true;
}
// Check for association on both source and target packages.
//读取pkg1的关联信息,看pkg2是否在允许的关联里
PackageAssociationInfo pai = mAllowedAssociations.get(pkg1);
if (pai != null && !pai.isPackageAssociationAllowed(pkg2)) {
return false;
}
//读取pkg2的关联信息,看pkg1是否在允许的关联里
pai = mAllowedAssociations.get(pkg2);
if (pai != null && !pai.isPackageAssociationAllowed(pkg1)) {
return false;
}
//默认返回true,比如默认配置如果为空的话
return true;
}
4.3.crashApplicationWithTypeWithExtras
小节5.5调用
public void crashApplicationWithTypeWithExtras(int uid, int initialPid, String packageName,
int userId, String message, boolean force, int exceptionTypeId,
@Nullable Bundle extras) {
if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
!= PackageManager.PERMISSION_GRANTED) {
//权限检查失败
throw new SecurityException(msg);
}
synchronized(this) {
//见9.1,使应用崩溃
mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId,
message, force, exceptionTypeId, extras);
}
}
4.4.MainHandler
final class MainHandler extends Handler {
>1.SERVICE_FOREGROUND_CRASH_MSG
case SERVICE_FOREGROUND_CRASH_MSG: {
SomeArgs args = (SomeArgs) msg.obj;
//见5.5
mServices.serviceForegroundCrash(
(ProcessRecord) args.arg1,
(String) args.arg2,
(ComponentName) args.arg3);
args.recycle();
} break;
>2.SERVICE_FOREGROUND_TIMEOUT_MSG
case SERVICE_FOREGROUND_TIMEOUT_MSG: {
//5.8处理
mServices.serviceForegroundTimeout((ServiceRecord) msg.obj);
} break;
>3.SERVICE_FOREGROUND_TIMEOUT_ANR_MSG
case SERVICE_FOREGROUND_TIMEOUT_ANR_MSG: {
SomeArgs args = (SomeArgs) msg.obj;
//5.12,启动超时ANR
mServices.serviceForegroundTimeoutANR((ProcessRecord) args.arg1,
(String) args.arg2);
args.recycle();
} break;
5.ActiveServices.java
5.1.startServiceLocked
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String
//.. 增加最后两个参数
return startServiceLocked(caller, service, resolvedType, callingPid, callingUid, fgRequired,
callingPackage, callingFeatureId, userId, false, null);
}
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 {
final boolean callerFg;
if (caller != null) {
//获取caller的进程信息
final ProcessRecord callerApp = mAm.getRecordForAppLOSP(caller);
if (callerApp == null) {
//caller信息为空,抛出异常
throw new SecurityException(//..
}
//非后台进程,那么就是前台
callerFg = callerApp.mState.getSetSchedGroup() != ProcessList.SCHED_GROUP_BACKGROUND;
} else {
//为空,那么调用者是前台的
callerFg = true;
}
//见5.2,检索要启动的服务
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;
//见补充1
setFgsRestrictionLocked(callingPackage, callingPid, callingUid, service, r, userId,
allowBackgroundActivityStarts);
if (!mAm.mUserController.exists(r.userId)) {
//user不存在
return null;
}
//
final boolean bgLaunch = !mAm.isUidActiveLOSP(r.appInfo.uid);
//
boolean forcedStandby = false;
if (bgLaunch && appRestrictedAnyInBackground(r.appInfo.uid, r.packageName)) {
//后台限制,改为标准的
forcedStandby = true;
}
if (fgRequired) {
if (r.mAllowStartForeground == REASON_DENIED && isBgFgsRestrictionEnabled(r)) {
//不允许启动前台服务,弹个通知
showFgsBgRestrictedNotificationLocked(r);
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) {
//检查op是否允许启动前台服务
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:
//不允许
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)) {
// 检查应用启动模式
final int allowed = mAm.getAppStartModeLOSP(r.appInfo.uid, r.packageName,
r.appInfo.targetSdkVersion, callingPid, false, false, forcedStandby);
if (allowed != ActivityManager.APP_START_MODE_NORMAL) {
//不允许
if (allowed == ActivityManager.APP_START_MODE_DELAYED || forceSilentAbort) {
return null;
}
if (forcedStandby) {
if (fgRequired) {
return null;
}
}
UidRecord uidRec = mAm.mProcessList.getUidRecordLOSP(r.appInfo.uid);
return new ComponentName("?", "app is in background uid " + uidRec);
}
}
//8.0以下的
if (r.appInfo.targetSdkVersion < Build.VERSION_CODES.O && fgRequired) {
fgRequired = false;
}
//如果包是冻结状态,等待解冻,就是加入pending集合里,后续处理
if (deferServiceBringupIfFrozenLocked(r, service, callingPackage, callingFeatureId,
callingUid, callingPid, fgRequired, callerFg, userId, allowBackgroundActivityStarts,
backgroundActivityStartsToken, false, null)) {
return null;
}
// 检查启动目标是否需要权限
if (!requestStartTargetPermissionsReviewIfNeededLocked(r, callingPackage, callingFeatureId,
callingUid, service, callerFg, userId, false, null)) {
return null;
}
//见5.4,启动服务,返回组件
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;
}
}
>1.setFgsRestrictionLocked
设置是否允许启动前台服务
- mFlagBackgroundFgsStartRestrictionEnabled,常量true,表明后台启动前台服务的显示是否打开。打开的话,那么从后台启动的前台服务将没有while-in-using权限(比如定位,拍照等)。
private void setFgsRestrictionLocked(String callingPackage,
int callingPid, int callingUid, Intent intent, ServiceRecord r, int userId,
boolean allowBackgroundActivityStarts) {
r.mLastSetFgsRestrictionTime = SystemClock.elapsedRealtime();
// Check DeviceConfig flag.
if (!mAm.mConstants.mFlagBackgroundFgsStartRestrictionEnabled) {
r.mAllowWhileInUsePermissionInFgs = true;
}
if (!r.mAllowWhileInUsePermissionInFgs
|| (r.mAllowStartForeground == REASON_DENIED)) {
final @ReasonCode int allowWhileInUse = shouldAllowFgsWhileInUsePermissionLocked(
callingPackage, callingPid, callingUid, r, allowBackgroundActivityStarts);
if (!r.mAllowWhileInUsePermissionInFgs) {
r.mAllowWhileInUsePermissionInFgs = (allowWhileInUse != REASON_DENIED);
}
if (r.mAllowStartForeground == REASON_DENIED) {
r.mAllowStartForeground = shouldAllowFgsStartForegroundWithBindingCheckLocked(
allowWhileInUse, callingPackage, callingPid, callingUid, intent, r,
userId);
}
}
}
5.2.retrieveServiceLocked
private ServiceLookupResult retrieveServiceLocked(Intent service,
String instanceName, boolean isSdkSandboxService, int sdkSandboxClientAppUid,
String sdkSandboxClientAppPackage, String resolvedType,
String callingPackage, int callingPid, int callingUid, int userId,
boolean createIfNeeded, boolean callingFromFg, boolean isBindExternal,//false
boolean allowInstant) {//false
ServiceRecord r = null;
userId = mAm.mUserController.handleIncomingUser(callingPid, callingUid, userId,
/* allowAll= */false, getAllowMode(service, callingPackage),
/* name= */ "service", callingPackage);
//获取用户的服务map,见补充1
ServiceMap smap = getServiceMapLocked(userId);
//service可能提供的是个别名,这里是找到最终的目标组件
final ComponentAliasResolver.Resolution<ComponentName> resolution =
mAm.mComponentAliasResolver.resolveService(service, resolvedType,
/* match flags */ 0, userId, callingUid);
final ComponentName comp;
if (instanceName == null) {
//参考5.1,会走这里
comp = service.getComponent();
} else {
final ComponentName realComp = service.getComponent();
if (realComp == null) {
throw new IllegalArgumentException("Can't use custom instance name '" + instanceName
+ "' without expicit component in Intent");
}
comp = new ComponentName(realComp.getPackageName(),
realComp.getClassName() + ":" + instanceName);
}
if (comp != null) {
//先通过组件名查找已有的serviceRecord,见5.3
r = smap.mServicesByInstanceName.get(comp);
}
if (r == null && !isBindExternal && instanceName == null) {
//没找到r,那么通过IntentFilter查找
Intent.FilterComparison filter = new Intent.FilterComparison(service);
//见5.3
r = smap.mServicesByIntent.get(filter);
}
if (r != null) {
//是否过滤对应用程序的访问,一般instant应用需要过滤
if (mAm.getPackageManagerInternal().filterAppAccess(r.packageName, callingUid,
userId)) {
//是的话返回空。
return null;
}
//外部服务,服务包名和调用者包名不一样,换句话说,外部服务在自己的包进程里运行
if ((r.serviceInfo.flags & ServiceInfo.FLAG_EXTERNAL_SERVICE) != 0
&& !callingPackage.equals(r.packageName)) {
//置空
r = null;
}
}
if (r == null) {
try {
int flags = ActivityManagerService.STOCK_PM_FLAGS
| PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
if (allowInstant) {
flags |= PackageManager.MATCH_INSTANT;
}
//读取服务info
ResolveInfo rInfo = mAm.getPackageManagerInternal().resolveService(service,
resolvedType, flags, userId, callingUid);
ServiceInfo sInfo = rInfo != null ? rInfo.serviceInfo : null;
if (sInfo == null) {
//没找到对应的服务
return null;
}
//..
ComponentName className = new ComponentName(sInfo.applicationInfo.packageName,
sInfo.name);
ComponentName name = comp != null ? comp : className;
//见4.2,验证callingPkg是否可以启动service包
if (!mAm.validateAssociationAllowedLocked(callingPackage, callingUid,
name.getPackageName(), sInfo.applicationInfo.uid)) {
String msg = "association not allowed between packages "
+ callingPackage + " and " + name.getPackageName();
//失败
return new ServiceLookupResult(msg);
}
//
String definingPackageName = sInfo.applicationInfo.packageName;
int definingUid = sInfo.applicationInfo.uid;
//服务里有外部服务的标志
if ((sInfo.flags & ServiceInfo.FLAG_EXTERNAL_SERVICE) != 0) {
//有BIND_EXTERNAL_SERVICE标志
if (isBindExternal) {
if (!sInfo.exported) {
//exported属性必须为true
throw new SecurityException("BIND_EXTERNAL_SERVICE failed, "
+ className + " is not exported");
}
if ((sInfo.flags & ServiceInfo.FLAG_ISOLATED_PROCESS) == 0) {
//isolated属性也必须为true,见补充2
throw new SecurityException("BIND_EXTERNAL_SERVICE failed, "
+ className + " is not an isolatedProcess");
}
//在caller包下运行服务
ApplicationInfo aInfo = AppGlobals.getPackageManager().getApplicationInfo(
callingPackage, ActivityManagerService.STOCK_PM_FLAGS, userId);
if (aInfo == null) {
throw new SecurityException("BIND_EXTERNAL_SERVICE failed, " +
"could not resolve client package " + callingPackage);
}
sInfo = new ServiceInfo(sInfo);
sInfo.applicationInfo = new ApplicationInfo(sInfo.applicationInfo);
sInfo.applicationInfo.packageName = aInfo.packageName;
sInfo.applicationInfo.uid = aInfo.uid;
name = new ComponentName(aInfo.packageName, name.getClassName());
className = new ComponentName(aInfo.packageName,
instanceName == null ? className.getClassName()
: (className.getClassName() + ":" + instanceName));
service.setComponent(name);
} else {
//缺少 BIND_EXTERNAL_SERVICE标志
throw new SecurityException("BIND_EXTERNAL_SERVICE required for " +
name);
}
} else if (isBindExternal) {
throw new SecurityException("BIND_EXTERNAL_SERVICE failed, " + name +
" is not an externalService");
}
if (userId > 0) {//非系统用户
//单例模式
if (mAm.isSingleton(sInfo.processName, sInfo.applicationInfo,
sInfo.name, sInfo.flags)
&& mAm.isValidSingletonCall(callingUid, sInfo.applicationInfo.uid)) {
userId = 0;
smap = getServiceMapLocked(0);
try {
ResolveInfo rInfoForUserId0 =
mAm.getPackageManagerInternal().resolveService(service,
resolvedType, flags, userId, callingUid);
if (rInfoForUserId0 == null) {
return null;
}
sInfo = rInfoForUserId0.serviceInfo;
}
}
sInfo = new ServiceInfo(sInfo);
sInfo.applicationInfo = mAm.getAppInfoForUser(sInfo.applicationInfo, userId);
}
r = smap.mServicesByInstanceName.get(name);
if (r == null && createIfNeeded) {
//没有找到旧的服务,创建新的
final Intent.FilterComparison filter
= new Intent.FilterComparison(service.cloneFilter());
//服务重启Runnable对象
final ServiceRestarter res = new ServiceRestarter();
String sdkSandboxProcessName = isSdkSandboxService ? instanceName : null;
//实例化新的对象
r = new ServiceRecord(mAm, className, name, definingPackageName,
definingUid, filter, sInfo, callingFromFg, res,
sdkSandboxProcessName, sdkSandboxClientAppUid,
sdkSandboxClientAppPackage);
res.setService(r);
//放入集合
smap.mServicesByInstanceName.put(name, r);
smap.mServicesByIntent.put(filter, r);
for (int i=mPendingServices.size()-1; i>=0; i--) {
final ServiceRecord pr = mPendingServices.get(i);
if (pr.serviceInfo.applicationInfo.uid == sInfo.applicationInfo.uid
&& pr.instanceName.equals(name)) {
//从等待的intent里移除,就是要启动的服务,等待服务的应用启动中
mPendingServices.remove(i);
}
}
for (int i = mPendingBringups.size() - 1; i >= 0; i--) {
final ServiceRecord pr = mPendingBringups.keyAt(i);
if (pr.serviceInfo.applicationInfo.uid == sInfo.applicationInfo.uid
&& pr.instanceName.equals(name)) {
//start或者bind的服务,还没ready的集合里移除
mPendingBringups.removeAt(i);
}
}
}
}
}
if (r != null) {
r.mRecentCallingPackage = callingPackage;
r.mRecentCallingUid = callingUid;
try {
//存储最后调用者的应用信息
r.mRecentCallerApplicationInfo =
mAm.mContext.getPackageManager().getApplicationInfoAsUser(callingPackage,
0, UserHandle.getUserId(callingUid));
} catch (PackageManager.NameNotFoundException e) {
}
//见4.2,咋又验证一次。。
if (!mAm.validateAssociationAllowedLocked(callingPackage, callingUid, r.packageName,
r.appInfo.uid)) {
String msg = "association not allowed between packages "
+ callingPackage + " and " + r.packageName;
//失败
return new ServiceLookupResult(msg);
}
//防火墙,就是一些配置,这里继续检查是否满足配置
if (!mAm.mIntentFirewall.checkService(r.name, service, callingUid, callingPid,
resolvedType, r.appInfo)) {
//失败
return new ServiceLookupResult("blocked by firewall");
}
//检查服务里声明需要的权限,
if (mAm.checkComponentPermission(r.permission,
callingPid, callingUid, r.appInfo.uid, r.exported) != PERMISSION_GRANTED) {
//权限检查失败
if (!r.exported) {
return new ServiceLookupResult("not exported from uid "
+ r.appInfo.uid);
}
return new ServiceLookupResult(r.permission);
} else if (Manifest.permission.BIND_HOTWORD_DETECTION_SERVICE.equals(r.permission)
&& callingUid != Process.SYSTEM_UID) {
//特殊权限,只能是系统才能启动
return new ServiceLookupResult("can only be bound to "
+ "by the system.");
} else if (r.permission != null && callingPackage != null) {
//权限转化为opCode,再次检查
final int opCode = AppOpsManager.permissionToOpCode(r.permission);
if (opCode != AppOpsManager.OP_NONE && mAm.getAppOpsManager().checkOpNoThrow(
opCode, callingUid, callingPackage) != AppOpsManager.MODE_ALLOWED) {
//失败
return null;
}
}
//成功
return new ServiceLookupResult(r, resolution.getAlias());
}
return null;
}
>1.getServiceMapLocked
获取对应用户的服务map
private ServiceMap getServiceMapLocked(int callingUser) {
ServiceMap smap = mServiceMap.get(callingUser);
if (smap == null) {
//没有的话创建新的,加入map
smap = new ServiceMap(mAm.mHandler.getLooper(), callingUser);
mServiceMap.put(callingUser, smap);
}
return smap;
}
>2.FLAG_EXTERNAL_SERVICE
externalService标签,也就是FLAG_EXTERNAL_SERVICE的作用
- exported ,externalService ,isolatedProcess 3个属性都必须设置为true
- bindService必须加对应的flag:BIND_EXTERNAL_SERVICE
- 就是说谁启动的这个服务,这个服务就在谁的进程下运行。
bindService(intent, mConnection, Context.BIND_AUTO_CREATE | Context.BIND_EXTERNAL_SERVICE);
<service
android:name=".MyTestService"
android:externalService="true"
android:isolatedProcess="true"
android:exported="true">
5.3.ServiceMap
Information about services for a single user.
final class ServiceMap extends Handler {
final int mUserId;
//组件名映射服务记录
final ArrayMap<ComponentName, ServiceRecord> mServicesByInstanceName = new ArrayMap<>();
final ArrayMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent = new ArrayMap<>();
final ArrayList<ServiceRecord> mDelayedStartList = new ArrayList<>();
5.4.startServiceInnerLocked
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)) {
}
final boolean wasStartRequested = r.startRequested;
r.lastActivity = SystemClock.uptimeMillis();
r.startRequested = true;//有人明确的调用了start方法启动的。
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;
//caller是后台的,启动的也不是前台服务,服务的进程记录为空
if (!callerFg && !fgRequired && r.app == null
&& mAm.mUserController.hasStartedUserState(r.userId)) {//用户已启动
//根据进程名和uid查找进程记录信息
ProcessRecord proc = mAm.getProcessRecordLocked(r.processName, r.appInfo.uid);
//没找到或者状态大于1010
if (proc == null || proc.mState.getCurProcState() > PROCESS_STATE_RECEIVER) {
if (r.delayed) {//后台等待启动服务为true
return r.name;
}
if (smap.mStartingBackground.size() >= mMaxStartingBackground) {
//后台启动的服务数超标了,加入delay集合里
smap.mDelayedStartList.add(r);
r.delayed = true;
return r.name;
}
addToStarting = true;
} else if (proc.mState.getCurProcState() >= ActivityManager.PROCESS_STATE_SERVICE) //1009{
addToStarting = true;
}
if (allowBackgroundActivityStarts) {//false
r.allowBgActivityStartsOnServiceStart(backgroundActivityStartsToken);
}
//见补充1
ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting,
callingUid, wasStartRequested);
return cmp;
}
>1.startServiceInnerLocked
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) {
//设置启动状态为true
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();
mAm.mBatteryStatsService.noteServiceStartRunning(uid, packageName, serviceName);
//见补充2,拉起服务
String error = bringUpServiceLocked(r, service.getFlags(), callerFg,
false /* whileRestarting */,
false /* permissionsReviewRequired */,
false /* packageFrozen */,
true /* enqueueOomAdj */);
mAm.updateOomAdjPendingTargetsLocked(OomAdjuster.OOM_ADJ_REASON_START_SERVICE);
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 (first) {
smap.rescheduleDelayedStartsLocked();
}
} else if (callerFg || r.fgRequired) {
//从后台启动服务集合里移除,从延迟启动服务里移除
smap.ensureNotStartingBackgroundLocked(r);
}
return r.name;
}
>2.bringUpServiceLocked
- 如果服务已经启动,会走5.4.4更新服务状态,最终走7.3.1,以及7.4,最后回到5.10。
- 如果服务还未启动,并且isolated为false(一般都是false,除非你手动声明为true),判断服务对应的应用是否已启动,启动话,那么启动对应的服务,见5.11以及7.3.2和7.5
- 继续判断如果应用未启动,那么启动应用,并把ServiceRecord加入mPendingServices等待应用启动成功再启动服务。
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
boolean whileRestarting, boolean permissionsReviewRequired, boolean packageFrozen,
boolean enqueueOomAdj){
//服务进程信息不为空,应用线程也不为空
if (r.app != null && r.app.getThread() != null) {
//见补充4,更新服务
sendServiceArgsLocked(r, execInFg, false);
return null;
}
if (!whileRestarting && mRestartingServices.contains(r)) {
// 等待重启中
return null;
}
//从集合移除
if (mRestartingServices.remove(r)) {
clearRestartingIfNeededLocked(r);
}
//如果在延迟启动集合里,移除,因为我们现在要启动它了。
if (r.delayed) {
getServiceMapLocked(r.userId).mDelayedStartList.remove(r);
r.delayed = false;
}
if (!mAm.mUserController.hasStartedUserState(r.userId)) {
//服务对应的user还没启动,干掉服务,见补充3
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);
}
//服务要启动了,它的包不能是stop状态
try {
AppGlobals.getPackageManager().setPackageStoppedState(
r.packageName, false, r.userId);
}
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;
if (!isolated) {//非隔离的服务,
app = mAm.getProcessRecordLocked(procName, r.appInfo.uid);
if (app != null) {//应用进程不为空
final IApplicationThread thread = app.getThread();
final int pid = app.getPid();
final UidRecord uidRecord = app.getUidRecord();
if (thread != null) {//主线程不为空
try {//加入集合
app.addPackage(r.appInfo.packageName, r.appInfo.longVersionCode,
mAm.mProcessStats);
//启动服务,见5.11
realStartServiceLocked(r, app, thread, pid, uidRecord, execInFg,
enqueueOomAdj);
return null;
}
}
}
} else {//运行在隔离的进程里,
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);
}
}
// 没有启动
if (app == null && !permissionsReviewRequired && !packageFrozen) {
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) {
//应用无法启动,停止服务,见补充3
bringDownServiceLocked(r, enqueueOomAdj);
return msg;
}
if (isolated) {
r.isolationHostProc = app;
}
}
if (r.fgRequired) {
//要启动前台服务,临时绕过省电模式
mAm.tempAllowlistUidLocked(r.appInfo.uid,
mAm.mConstants.mServiceStartForegroundTimeoutMs, REASON_SERVICE_LAUNCH,
"fg-service-launch",
TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
r.mRecentCallingUid);
}
//加入pending,上边应用启动以后,会查找这个集合再启动对应的服务
if (!mPendingServices.contains(r)) {
mPendingServices.add(r);
}
if (r.delayedStop) {
// 延迟停止状态
r.delayedStop = false;
if (r.startRequested) {//又需要启动
stopServiceLocked(r, enqueueOomAdj);
}
}
return null;
}
>3.bringDownServiceLocked
这个方法被调用的地方有点多,有差不多10处了。
private void bringDownServiceLocked(ServiceRecord r, boolean enqueueOomAdj) {
ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections = r.getConnections();
for (int conni = connections.size() - 1; conni >= 0; conni--) {
ArrayList<ConnectionRecord> c = connections.valueAt(conni);
for (int i=0; i<c.size(); i++) {
ConnectionRecord cr = c.get(i);
// 报告所有的连接,服务不可用
cr.serviceDead = true;
cr.stopAssociation();
final ComponentName clientSideComponentName =
cr.aliasComponent != null ? cr.aliasComponent : r.name;
try {//就是调用ServiceConnection的onBindingDied方法
cr.conn.connected(r.name, null, true);//true表示dead
}
}
}
boolean oomAdjusted = false;
// 告诉服务它已解除绑定
if (r.app != null && r.app.getThread() != null) {
for (int i = r.bindings.size() - 1; i >= 0; i--) {
IntentBindRecord ibr = r.bindings.valueAt(i);
if (ibr.hasBound) {
try {
oomAdjusted |= bumpServiceExecutingLocked(r, false, "bring down unbind",
OomAdjuster.OOM_ADJ_REASON_UNBIND_SERVICE);
ibr.hasBound = false;
ibr.requested = false;
r.app.getThread().scheduleUnbindService(r,
ibr.intent.getIntent());
}
}
}
}
if (r.fgRequired) {
r.fgRequired = false;
r.fgWaiting = false;
synchronized (mAm.mProcessStats.mLock) {
ServiceState stracker = r.getTracker();
if (stracker != null) {
//设置前台服务为false
stracker.setForeground(false, mAm.mProcessStats.getMemFactorLocked(),
SystemClock.uptimeMillis());
}
}
//结束启动前台服务的操作
mAm.mAppOpsService.finishOperation(AppOpsManager.getToken(mAm.mAppOpsService),
AppOpsManager.OP_START_FOREGROUND, r.appInfo.uid, r.packageName, null);
mAm.mHandler.removeMessages(
ActivityManagerService.SERVICE_FOREGROUND_TIMEOUT_MSG, r);
if (r.app != null) {
//发送crash的消息,见4.4.1
Message msg = mAm.mHandler.obtainMessage(
ActivityManagerService.SERVICE_FOREGROUND_CRASH_MSG);
SomeArgs args = SomeArgs.obtain();
args.arg1 = r.app;
args.arg2 = r.toString();
args.arg3 = r.getComponentName();
msg.obj = args;
mAm.mHandler.sendMessage(msg);
}
}
r.destroyTime = SystemClock.uptimeMillis();
final ServiceMap smap = getServiceMapLocked(r.userId);
ServiceRecord found = smap.mServicesByInstanceName.remove(r.instanceName);
// Note when this method is called by bringUpServiceLocked(), the service is not found
// in mServicesByInstanceName and found will be null.
if (found != null && found != r) {
// This is not actually the service we think is running... this should not happen,
// but if it does, fail hard.
smap.mServicesByInstanceName.put(r.instanceName, found);
throw new IllegalStateException("Bringing down " + r + " but actually running "
+ found);
}
smap.mServicesByIntent.remove(r.intent);
r.totalRestartCount = 0;
unscheduleServiceRestartLocked(r, 0, true);
// Also make sure it is not on the pending list.
for (int i=mPendingServices.size()-1; i>=0; i--) {
if (mPendingServices.get(i) == r) {
mPendingServices.remove(i);
}
}
cancelForegroundNotificationLocked(r);
final boolean exitingFg = r.isForeground;
if (exitingFg) {
decActiveForegroundAppLocked(smap, r);
synchronized (mAm.mProcessStats.mLock) {
ServiceState stracker = r.getTracker();
if (stracker != null) {
stracker.setForeground(false, mAm.mProcessStats.getMemFactorLocked(),
SystemClock.uptimeMillis());
}
}
mAm.mAppOpsService.finishOperation(
AppOpsManager.getToken(mAm.mAppOpsService),
AppOpsManager.OP_START_FOREGROUND, r.appInfo.uid, r.packageName, null);
unregisterAppOpCallbackLocked(r);
r.mFgsExitTime = SystemClock.uptimeMillis();
mAm.updateForegroundServiceUsageStats(r.name, r.userId, false);
}
r.isForeground = false;
r.mFgsNotificationWasDeferred = false;
dropFgsNotificationStateLocked(r);
r.foregroundId = 0;
r.foregroundNoti = null;
resetFgsRestrictionLocked(r);
if (exitingFg) {
signalForegroundServiceObserversLocked(r);
}
// Clear start entries.
r.clearDeliveredStartsLocked();
r.pendingStarts.clear();
smap.mDelayedStartList.remove(r);
if (r.app != null) {
mAm.mBatteryStatsService.noteServiceStopLaunch(r.appInfo.uid, r.name.getPackageName(),
r.name.getClassName());
stopServiceAndUpdateAllowlistManagerLocked(r);
if (r.app.getThread() != null) {
// Bump the process to the top of LRU list
mAm.updateLruProcessLocked(r.app, false, null);
updateServiceForegroundLocked(r.app.mServices, false);
try {
oomAdjusted |= bumpServiceExecutingLocked(r, false, "destroy",
oomAdjusted ? null : OomAdjuster.OOM_ADJ_REASON_UNBIND_SERVICE);
mDestroyingServices.add(r);
r.destroying = true;
r.app.getThread().scheduleStopService(r);
} catch (Exception e) {
Slog.w(TAG, "Exception when destroying service "
+ r.shortInstanceName, e);
serviceProcessGoneLocked(r, enqueueOomAdj);
}
}
}
if (!oomAdjusted) {
mAm.enqueueOomAdjTargetLocked(r.app);
if (!enqueueOomAdj) {
mAm.updateOomAdjPendingTargetsLocked(OomAdjuster.OOM_ADJ_REASON_UNBIND_SERVICE);
}
}
if (r.bindings.size() > 0) {
r.bindings.clear();
}
if (r.restarter instanceof ServiceRestarter) {
((ServiceRestarter)r.restarter).setService(null);
}
synchronized (mAm.mProcessStats.mLock) {
final int memFactor = mAm.mProcessStats.getMemFactorLocked();
if (r.tracker != null) {
final long now = SystemClock.uptimeMillis();
r.tracker.setStarted(false, memFactor, now);
r.tracker.setBound(false, memFactor, now);
if (r.executeNesting == 0) {
r.tracker.clearCurrentOwner(r, false);
r.tracker = null;
}
}
}
smap.ensureNotStartingBackgroundLocked(r);
updateNumForegroundServicesLocked();
}
>4.sendServiceArgsLocked
走到这里说明有已经启动的服务
- 这里添加了超时msg,具体见5.9
private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
boolean oomAdjusted) throws TransactionTooLargeException {
final int N = r.pendingStarts.size();
if (N == 0) {
return;
}
ArrayList<ServiceStartArgs> args = new ArrayList<>();
while (r.pendingStarts.size() > 0) {
ServiceRecord.StartItem si = r.pendingStarts.remove(0);
if (si.intent == null && N > 1) {
continue;
}
si.deliveredTime = SystemClock.uptimeMillis();
//加入已投递集合
r.deliveredStarts.add(si);
si.deliveryCount++;
if (si.neededGrants != null) {
//服务如果有需要的权限的话,进行验证
mAm.mUgmInternal.grantUriPermissionUncheckedFromIntent(si.neededGrants,
si.getUriPermissionsLocked());
}
mAm.grantImplicitAccess(r.userId, si.intent, si.callingId,
UserHandle.getAppId(r.appInfo.uid)
);
//服务进入执行状态
bumpServiceExecutingLocked(r, execInFg, "start", null /* oomAdjReason */);
//需要前台服务并且进入前台服务超时时间还未设置
if (r.fgRequired && !r.fgWaiting) {
if (!r.isForeground) {//还不是前台服务
//添加进入前台服务超时时间,见5.9
scheduleServiceForegroundTransitionTimeoutLocked(r);
} else {//已经是前台服务了,那么需求的标志改为false
r.fgRequired = false;
}
}
int flags = 0;
if (si.deliveryCount > 1) {
flags |= Service.START_FLAG_RETRY;
}
if (si.doneExecutingCount > 0) {
flags |= Service.START_FLAG_REDELIVERY;
}
//加入集合
args.add(new ServiceStartArgs(si.taskRemoved, si.id, flags, si.intent));
}
if (!oomAdjusted) {
mAm.enqueueOomAdjTargetLocked(r.app);
mAm.updateOomAdjPendingTargetsLocked(OomAdjuster.OOM_ADJ_REASON_START_SERVICE);
}
//args放入集合
ParceledListSlice<ServiceStartArgs> slice = new ParceledListSlice<>(args);
slice.setInlineCountLimit(4);
Exception caughtException = null;
try {//见7.3.1
r.app.getThread().scheduleServiceArgs(r, slice);
}catch
//..
}
5.5.serviceForegroundCrash
使前台服务崩溃
void serviceForegroundCrash(ProcessRecord app, String serviceRecord,
ComponentName service) {
//又回到4.3
mAm.crashApplicationWithTypeWithExtras(
app.uid, app.getPid(), app.info.packageName, app.userId,
"Context.startForegroundService() did not then call " + "Service.startForeground(): "
+ serviceRecord, false /*force*/,
ForegroundServiceDidNotStartInTimeException.TYPE_ID,
ForegroundServiceDidNotStartInTimeException.createExtrasForService(service));
}
5.6.setServiceForegroundLocked
- 小节6.4,id一般不为0,notification不为空,flags为0,foregroundServiceType不为0
- 小节6.5,id为0,notification为空,flags为0,1,2,foregroundServiceType为0
public void setServiceForegroundLocked(ComponentName className, IBinder token,
int id, Notification notification, int flags, int foregroundServiceType) {
try {
//根据组件名找到已有的r
ServiceRecord r = findServiceLocked(className, token, userId);
if (r != null) {
//见5.7,设置为前台服务状态
setServiceForegroundInnerLocked(r, id, notification, flags, foregroundServiceType);
}
}
}
5.7.setServiceForegroundInnerLocked
private void setServiceForegroundInnerLocked(final ServiceRecord r, int id,
Notification notification, int flags, int foregroundServiceType) {
if (id != 0) {//正常是启动前台通知
if (notification == null) {
throw new IllegalArgumentException("null notification");
}
// Instant apps 需要权限创建前台服务
if (r.appInfo.isInstantApp()) {
final int mode = mAm.getAppOpsManager().checkOpNoThrow(
AppOpsManager.OP_INSTANT_APP_START_FOREGROUND,
r.appInfo.uid,
r.appInfo.packageName);
switch (mode) {
case AppOpsManager.MODE_ALLOWED://权限已允许
break;
case AppOpsManager.MODE_IGNORED:
//无视,那么返回
return;
case AppOpsManager.MODE_ERRORED:
throw new SecurityException("Instant app " + r.appInfo.packageName
+ " does not have permission to create foreground services");
default://检查权限
mAm.enforcePermission(
android.Manifest.permission.INSTANT_APP_FOREGROUND_SERVICE,
r.app.getPid(), r.appInfo.uid, "startForeground");
}
} else {//正常的应用
if (r.appInfo.targetSdkVersion >= Build.VERSION_CODES.P) {
//检查权限
mAm.enforcePermission(
android.Manifest.permission.FOREGROUND_SERVICE,
r.app.getPid(), r.appInfo.uid, "startForeground");
}
int manifestType = r.serviceInfo.getForegroundServiceType();
//
if (foregroundServiceType == FOREGROUND_SERVICE_TYPE_MANIFEST) {
foregroundServiceType = manifestType;
}
//
if ((foregroundServiceType & manifestType) != foregroundServiceType) {
throw new IllegalArgumentException("foregroundServiceType "
//..
}
}
boolean alreadyStartedOp = false;
boolean stopProcStatsOp = false;
if (r.fgRequired) {
r.fgRequired = false;
r.fgWaiting = false;
alreadyStartedOp = stopProcStatsOp = true;
//移除前台服务超时msg,5.9里添加的
mAm.mHandler.removeMessages(
ActivityManagerService.SERVICE_FOREGROUND_TIMEOUT_MSG, r);
}
final ProcessServiceRecord psr = r.app.mServices;
try {
boolean ignoreForeground = false;
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:
//启动前台服务的操作不允许
ignoreForeground = true;
break;
default:
throw new SecurityException("Foreground not allowed as per app op");
}
if (!ignoreForeground
&& !isForegroundServiceAllowedInBackgroundRestricted(r.app)) {
updateServiceForegroundLocked(psr, false);
ignoreForeground = true;
}
if (!ignoreForeground) {
if (r.mStartForegroundCount == 0) {//已启动的前台服务数为0
if (!r.fgRequired) {//不需要前台服务
final long delayMs = SystemClock.elapsedRealtime() - r.createRealTime;
if (delayMs > mAm.mConstants.mFgsStartForegroundTimeoutMs) {
resetFgsRestrictionLocked(r);
setFgsRestrictionLocked(r.serviceInfo.packageName, r.app.getPid(),
r.appInfo.uid, r.intent.getIntent(), r, r.userId, false);
//..
}
}
} else if (r.mStartForegroundCount >= 1) {
//
setFgsRestrictionLocked(r.serviceInfo.packageName, r.app.getPid(),
r.appInfo.uid, r.intent.getIntent(), r, r.userId, false);
}
//不允许启动前台服务
if (r.mAllowStartForeground == REASON_DENIED && isBgFgsRestrictionEnabled(r)) {
showFgsBgRestrictedNotificationLocked(r);
updateServiceForegroundLocked(psr, true);
ignoreForeground = true;
if (CompatChanges.isChangeEnabled(FGS_START_EXCEPTION_CHANGE_ID,
r.appInfo.uid)) {
throw new ForegroundServiceStartNotAllowedException(msg);
}
}
}
if (!ignoreForeground) {
if (r.foregroundId != id) {
cancelForegroundNotificationLocked(r);
r.foregroundId = id;
}
notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
r.foregroundNoti = notification;
r.foregroundServiceType = foregroundServiceType;
if (!r.isForeground) {
final ServiceMap smap = getServiceMapLocked(r.userId);
if (smap != null) {
ActiveForegroundApp active = smap.mActiveForegroundApps
.get(r.packageName);
if (active == null) {
active = new ActiveForegroundApp();
active.mPackageName = r.packageName;
active.mUid = r.appInfo.uid;
active.mShownWhileScreenOn = mScreenOn;
if (r.app != null) {
final UidRecord uidRec = r.app.getUidRecord();
if (uidRec != null) {
active.mAppOnTop = active.mShownWhileTop =
uidRec.getCurProcState() <= PROCESS_STATE_TOP;
}
}
active.mStartTime = active.mStartVisibleTime
= SystemClock.elapsedRealtime();
smap.mActiveForegroundApps.put(r.packageName, active);
requestUpdateActiveForegroundAppsLocked(smap, 0);
}
active.mNumActive++;
}
//到这里才算已经是前台服务了。
r.isForeground = true;
r.mAllowStartForegroundAtEntering = r.mAllowStartForeground;
r.mAllowWhileInUsePermissionInFgsAtEntering =
r.mAllowWhileInUsePermissionInFgs;
r.mStartForegroundCount++;
r.mFgsEnterTime = SystemClock.uptimeMillis();
if (!stopProcStatsOp) {
synchronized (mAm.mProcessStats.mLock) {
final ServiceState stracker = r.getTracker();
if (stracker != null) {
stracker.setForeground(true,
mAm.mProcessStats.getMemFactorLocked(),
SystemClock.uptimeMillis());
}
}
} else {
stopProcStatsOp = false;
}
//启动前台服务操作
mAm.mAppOpsService.startOperation(
AppOpsManager.getToken(mAm.mAppOpsService),
AppOpsManager.OP_START_FOREGROUND, r.appInfo.uid, r.packageName,
null, true, false, "", false, AppOpsManager.ATTRIBUTION_FLAGS_NONE,
AppOpsManager.ATTRIBUTION_CHAIN_ID_NONE);
registerAppOpCallbackLocked(r);
mAm.updateForegroundServiceUsageStats(r.name, r.userId, true);
updateNumForegroundServicesLocked();
}
signalForegroundServiceObserversLocked(r);
//显示通知,见10.2
r.postNotification();
if (r.app != null) {
updateServiceForegroundLocked(psr, true);
}
getServiceMapLocked(r.userId).ensureNotStartingBackgroundLocked(r);
mAm.notifyPackageUse(r.serviceInfo.packageName,
PackageManager.NOTIFY_PACKAGE_USE_FOREGROUND_SERVICE);
}
} finally {
if (stopProcStatsOp) {
synchronized (mAm.mProcessStats.mLock) {
final ServiceState stracker = r.getTracker();
if (stracker != null) {
stracker.setForeground(false, mAm.mProcessStats.getMemFactorLocked(),
SystemClock.uptimeMillis());
}
}
}
if (alreadyStartedOp) {
mAm.mAppOpsService.finishOperation(
AppOpsManager.getToken(mAm.mAppOpsService),
AppOpsManager.OP_START_FOREGROUND, r.appInfo.uid, r.packageName,
null);
}
}
} else {//这里是通知id等于0的情况,一般是停止前台通知
if (r.isForeground) {
final ServiceMap smap = getServiceMapLocked(r.userId);
if (smap != null) {
decActiveForegroundAppLocked(smap, r);
}
if ((flags & Service.STOP_FOREGROUND_REMOVE) != 0) {
//取消通知
cancelForegroundNotificationLocked(r);
r.foregroundId = 0;
r.foregroundNoti = null;
} else if (r.appInfo.targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP) {
// if it's been deferred, force to visibility
if (!r.mFgsNotificationShown) {
r.postNotification();
}
//如果没有其他前台服务公用这个通知,那么移除所有相关的flag,否则啥也不做
dropFgsNotificationStateLocked(r);
if ((flags & Service.STOP_FOREGROUND_DETACH) != 0) {
r.foregroundId = 0;
r.foregroundNoti = null;
}
}
r.isForeground = false;
r.mFgsExitTime = SystemClock.uptimeMillis();
synchronized (mAm.mProcessStats.mLock) {
final ServiceState stracker = r.getTracker();
if (stracker != null) {
//设置前台标志为false
stracker.setForeground(false, mAm.mProcessStats.getMemFactorLocked(),
SystemClock.uptimeMillis());
}
}
mAm.mAppOpsService.finishOperation(
AppOpsManager.getToken(mAm.mAppOpsService),
AppOpsManager.OP_START_FOREGROUND, r.appInfo.uid, r.packageName, null);
unregisterAppOpCallbackLocked(r);
r.mFgsNotificationWasDeferred = false;
signalForegroundServiceObserversLocked(r);
resetFgsRestrictionLocked(r);
mAm.updateForegroundServiceUsageStats(r.name, r.userId, false);
if (r.app != null) {
mAm.updateLruProcessLocked(r.app, false, null);
updateServiceForegroundLocked(r.app.mServices, true);
}
updateNumForegroundServicesLocked();
}
}
}
5.8.serviceForegroundTimeout
4.4.2调用,前台服务超时处理,处理的就是5.9的msg
void serviceForegroundTimeout(ServiceRecord r) {
ProcessRecord app;
synchronized (mAm) {
if (!r.fgRequired || !r.fgWaiting || r.destroying) {
//非前台服务或者非前台服务等待中或者服务已销毁
return;
}
app = r.app;
if (app != null && app.isDebugging()) {
//测试中,忽略
return;
}
r.fgWaiting = false;
//见补充1,停止服务
stopServiceLocked(r, false);
}
if (app != null) {
//就是说startForegroundService以后,需要在规定时间30s以内调用startForeground启动前台通知
final String annotation = "Context.startForegroundService() did not then call "
+ "Service.startForeground(): " + r;
//4.4.3处理
Message msg = mAm.mHandler.obtainMessage(
ActivityManagerService.SERVICE_FOREGROUND_TIMEOUT_ANR_MSG);
SomeArgs args = SomeArgs.obtain();
args.arg1 = app;
args.arg2 = annotation;
msg.obj = args;
mAm.mHandler.sendMessageDelayed(msg,
mAm.mConstants.mServiceStartForegroundAnrDelayMs);
}
}
>1.stopServiceLocked
private void stopServiceLocked(ServiceRecord service, boolean enqueueOomAdj) {
if (service.delayed) {
//说明服务还没启动,只是在延迟启动的列表了,还是让它启动,一旦启动,立马停止
service.delayedStop = true;
return;
}
final int uid = service.appInfo.uid;
final String packageName = service.name.getPackageName();
final String serviceName = service.name.getClassName();
mAm.mBatteryStatsService.noteServiceStopRunning(uid, packageName, serviceName);
service.startRequested = false;
if (service.tracker != null) {
synchronized (mAm.mProcessStats.mLock) {
//修改活动状态为false
service.tracker.setStarted(false, mAm.mProcessStats.getMemFactorLocked(),
SystemClock.uptimeMillis());
}
}
service.callStart = false;
//见补充2
bringDownServiceIfNeededLocked(service, false, false, enqueueOomAdj);
}
>2.bringDownServiceIfNeededLocked
private final void bringDownServiceIfNeededLocked(ServiceRecord r, boolean knowConn,
boolean hasConn, boolean enqueueOomAdj) {
//见补充3
if (isServiceNeededLocked(r, knowConn, hasConn)) {
//服务还需要
return;
}
//服务还没启动
if (mPendingServices.contains(r)) {
return;
}
//见5.4.3
bringDownServiceLocked(r, enqueueOomAdj);
}
>3.isServiceNeededLocked
判断服务是否还需要
private final boolean isServiceNeededLocked(ServiceRecord r, boolean knowConn,
boolean hasConn) {
// Are we still explicitly being asked to run?
if (r.startRequested) {
return true;
}
// Is someone still bound to us keeping us running?
if (!knowConn) {
//是否自动创建
hasConn = r.hasAutoCreateConnections();
}
if (hasConn) {
return true;
}
return false;
}
5.9.scheduleServiceForegroundTransitionTimeoutLocked
参考5.4.4,服务启动以后会调用
- 可以在这个方法里过滤包名,不启动超时检测服务,那么对应的前台服务也就不需要前台通知了。
void scheduleServiceForegroundTransitionTimeoutLocked(ServiceRecord r) {
if (r.app.mServices.numberOfExecutingServices() == 0 || r.app.getThread() == null) {
return;
}
//见4.4.2,前台服务启动超时msg,msg最终调用的是5.8的方法
Message msg = mAm.mHandler.obtainMessage(
ActivityManagerService.SERVICE_FOREGROUND_TIMEOUT_MSG);
msg.obj = r;
r.fgWaiting = true;
//延迟时间是常量30秒
mAm.mHandler.sendMessageDelayed(msg, mAm.mConstants.mServiceStartForegroundTimeoutMs);
}
下边贴下启动超时msg啥时候被取消的
>1.setServiceForegroundInnerLocked
调用startForeground方法启动前台通知的时候会调用,见6.4
private void setServiceForegroundInnerLocked(final ServiceRecord r, int id,
//..
if (id != 0) {
//..
if (r.fgRequired) {
r.fgRequired = false;
r.fgWaiting = false;
alreadyStartedOp = stopProcStatsOp = true;
//移除
mAm.mHandler.removeMessages(
ActivityManagerService.SERVICE_FOREGROUND_TIMEOUT_MSG, r);
}
>2.performScheduleRestartLocked
计划重启服务中
void performScheduleRestartLocked(ServiceRecord r, @NonNull String scheduling,
@NonNull String reason, @UptimeMillisLong long now) {
if (r.fgRequired && r.fgWaiting) {
mAm.mHandler.removeMessages(
ActivityManagerService.SERVICE_FOREGROUND_TIMEOUT_MSG, r);
r.fgWaiting = false;
}
>3.bringDownServiceLocked
干掉服务的时候
private void bringDownServiceLocked(ServiceRecord r, boolean enqueueOomAdj) {
//..
if (r.fgRequired) {
//..
mAm.mHandler.removeMessages(
ActivityManagerService.SERVICE_FOREGROUND_TIMEOUT_MSG, r);
5.10.serviceDoneExecutingLocked
Service完成了某种操作,小节7.4调用
void serviceDoneExecutingLocked(ServiceRecord r, int type, int startId, int res,
boolean enqueueOomAdj) {
boolean inDestroying = mDestroyingServices.contains(r);
if (r != null) {
if (type == ActivityThread.SERVICE_DONE_EXECUTING_START) {
r.callStart = true;
switch (res) {
case Service.START_STICKY_COMPATIBILITY:
case Service.START_STICKY: {//粘性服务
//移除投递集合里的数据
r.findDeliveredStart(startId, false, true);
//被杀死的时候是否停止服务
r.stopIfKilled = false;
break;
}
case Service.START_NOT_STICKY: {
r.findDeliveredStart(startId, false, true);
if (r.getLastStartId() == startId) {
r.stopIfKilled = true;
}
break;
}
//..
} else if (type == ActivityThread.SERVICE_DONE_EXECUTING_STOP) {
//..
}
serviceDoneExecutingLocked(r, inDestroying, inDestroying, enqueueOomAdj);
}
}
5.11.realStartServiceLocked
真正的创建服务实例
private void realStartServiceLocked(ServiceRecord r, ProcessRecord app,
IApplicationThread thread, int pid, UidRecord uidRecord, boolean execInFg,
boolean enqueueOomAdj) throws RemoteException {
//更新进程信息
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 */);
mAm.updateLruProcessLocked(app, false, null);
updateServiceForegroundLocked(psr, /* oomAdj= */ false);
mAm.enqueueOomAdjTargetLocked(app);
mAm.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_START_SERVICE);
boolean created = false;
try {
final int uid = r.appInfo.uid;
final String packageName = r.name.getPackageName();
final String serviceName = r.name.getClassName();
mAm.mBatteryStatsService.noteServiceStartLaunch(uid, packageName, serviceName);
mAm.notifyPackageUse(r.serviceInfo.packageName,
PackageManager.NOTIFY_PACKAGE_USE_SERVICE);
//这里是真正的创建服务,见7.3.2
thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo),
app.mState.getReportedProcState());
r.postNotification();
created = true;
}
if (r.allowlistManager) {
psr.mAllowlistManager = true;
}
//处理bindService数据
requestServiceBindingsLocked(r, execInFg);
updateServiceClientActivitiesLocked(psr, null, true);
if (newService && created) {
//新加入启动的服务,放入bound集合,方便后续bindService使用
psr.addBoundClientUidsOfNewService(r);
}
//服务处于启动状态,且没有挂起的参数,那么伪造一个,这样它就可以调用onStartCommand方法了
if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
null, null, 0));
}
//见5.4.4,上边伪造了一个数据加入集合
sendServiceArgsLocked(r, execInFg, true);
if (r.delayed) {//从延迟启动集合里移除
getServiceMapLocked(r.userId).mDelayedStartList.remove(r);
r.delayed = false;
}
if (r.delayedStop) {//延迟停止的
r.delayedStop = false;
if (r.startRequested) {
//停止服务
stopServiceLocked(r, enqueueOomAdj);
}
}
}
5.12.serviceForegroundTimeoutANR
void serviceForegroundTimeoutANR(ProcessRecord app, String annotation) {
mAm.mAnrHelper.appNotResponding(app, annotation);
}
6.Service.java
6.1.setStartForegroundServiceStackTrace
- StackTrace是Exception的子类,构造方法里传递异常提示文字
- 启动前台服务的时候,先保存类名和异常对象,等到前台服务启动异常以后,再根据类名找到这个异常对象,然后抛出。
/**
* This keeps track of the stacktrace where Context.startForegroundService() was called
* for each service class. We use that when we crash the app for not calling
* {@link #startForeground} in time, in {@link ActivityThread#throwRemoteServiceException}.
*/
@GuardedBy("sStartForegroundServiceStackTraces")
private static final ArrayMap<String, StackTrace> sStartForegroundServiceStackTraces =
new ArrayMap<>();
//添加新的前台服务对应的异常
public static void setStartForegroundServiceStackTrace(
@NonNull String className, @NonNull StackTrace stacktrace) {
synchronized (sStartForegroundServiceStackTraces) {
sStartForegroundServiceStackTraces.put(className, stacktrace);
}
}
6.2.clearStartForegroundServiceStackTrace
//清除所有map数据
private void clearStartForegroundServiceStackTrace() {
synchronized (sStartForegroundServiceStackTraces) {
sStartForegroundServiceStackTraces.remove(this.getClassName());
}
}
6.3.getStartForegroundServiceStackTrace
//根据类名获取异常对象
public static StackTrace getStartForegroundServiceStackTrace(@NonNull String className) {
synchronized (sStartForegroundServiceStackTraces) {
return sStartForegroundServiceStackTraces.get(className);
}
}
6.4.startForeground
public final void startForeground(int id, Notification notification) {
try {
//最终走到5.6
mActivityManager.setServiceForeground(
new ComponentName(this, mClassName), mToken, id,
notification, 0, FOREGROUND_SERVICE_TYPE_MANIFEST);
//见6.2,清除保存在异常map里的数据
clearStartForegroundServiceStackTrace();
} catch (RemoteException ex) {
}
}
public final void startForeground(int id, @NonNull Notification notification,
@ForegroundServiceType int foregroundServiceType) {
try {
mActivityManager.setServiceForeground(
new ComponentName(this, mClassName), mToken, id,
notification, 0, foregroundServiceType);
//见6.2
clearStartForegroundServiceStackTrace();
} catch (RemoteException ex) {
}
}
6.5.stopForeground
public final void stopForeground(boolean removeNotification) {
stopForeground(removeNotification ? STOP_FOREGROUND_REMOVE : STOP_FOREGROUND_LEGACY);
}
public final void stopForeground(@StopForegroundSelector int notificationBehavior) {
try {//见5.6
mActivityManager.setServiceForeground(
new ComponentName(this, mClassName), mToken, 0, null,
notificationBehavior, 0);
} catch (RemoteException ex) {
}
}
>1.StopForegroundSelector
STOP_FOREGROUND_LEGACY, //0
STOP_FOREGROUND_REMOVE, //1
STOP_FOREGROUND_DETACH //2
7.ActivityThread.java
7.1.Handler
class H extends Handler {
>1.SCHEDULE_CRASH
case SCHEDULE_CRASH: {
SomeArgs args = (SomeArgs) msg.obj;
String message = (String) args.arg1;
Bundle extras = (Bundle) args.arg2;
args.recycle();
//见7.2.1
throwRemoteServiceException(message, msg.arg1, extras);
break;
}
7.2.scheduleCrash
public void scheduleCrash(String msg, int typeId, @Nullable Bundle extras) {
SomeArgs args = SomeArgs.obtain();
args.arg1 = msg;
args.arg2 = extras;
//见7.1.1
sendMessage(H.SCHEDULE_CRASH, args, typeId);
}
>1.throwRemoteServiceException
抛出服务异常,根据type不同,异常也不同
private void throwRemoteServiceException(String message, int typeId, @Nullable Bundle extras) {
// Use a switch to ensure all the type IDs are unique.
switch (typeId) {
//前台服务没有在规定时间启动
case ForegroundServiceDidNotStartInTimeException.TYPE_ID:
//见补充2
throw generateForegroundServiceDidNotStartInTimeException(message, extras);
case CannotDeliverBroadcastException.TYPE_ID:
throw new CannotDeliverBroadcastException(message);
case CannotPostForegroundServiceNotificationException.TYPE_ID:
throw new CannotPostForegroundServiceNotificationException(message);
case BadForegroundServiceNotificationException.TYPE_ID:
throw new BadForegroundServiceNotificationException(message);
case MissingRequestPasswordComplexityPermissionException.TYPE_ID:
throw new MissingRequestPasswordComplexityPermissionException(message);
case CrashedByAdbException.TYPE_ID:
throw new CrashedByAdbException(message);
default:
throw new RemoteServiceException(message
+ " (with unwknown typeId:" + typeId + ")");
}
}
>2.generateForegroundServiceDidNotStartInTimeException
private ForegroundServiceDidNotStartInTimeException
generateForegroundServiceDidNotStartInTimeException(String message, Bundle extras) {
//根据key="serviceclassname"获取服务类名
final String serviceClassName =
ForegroundServiceDidNotStartInTimeException.getServiceClassNameFromExtras(extras);
//根据类名找到之前保存的异常对象,见6.3
final Exception inner = (serviceClassName == null) ? null
: Service.getStartForegroundServiceStackTrace(serviceClassName);
//抛出远程异常
throw new ForegroundServiceDidNotStartInTimeException(message, inner);
}
7.3.ApplicationThread
>1.scheduleServiceArgs
更新服务参数,一般是服务已经启动了,再次调用start或者bindService等
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);
}
}
>2.scheduleCreateService
创建新的服务
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);
}
7.4.handleServiceArgs
private void handleServiceArgs(ServiceArgsData data) {
CreateServiceData createData = mServicesData.get(data.token);
Service s = mServices.get(data.token);
if (s != null) {
try {
if (data.args != null) {
data.args.setExtrasClassLoader(s.getClassLoader());
data.args.prepareToEnterProcess(isProtectedComponent(createData.info),
s.getAttributionSource());
}
int res;
if (!data.taskRemoved) {
//调用服务onStartCommand方法
res = s.onStartCommand(data.args, data.flags, data.startId);
} else {//task被移除,调用服务对应的方法
s.onTaskRemoved(data.args);
res = Service.START_TASK_REMOVED_COMPLETE;
}
QueuedWork.waitToFinish();
try {//见5.10
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_START, data.startId, res);
}
}
}
}
7.5.handleCreateService
private void handleCreateService(CreateServiceData data) {
//取消gc操作
unscheduleGcIdler();
//获取安装包信息
LoadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo);
Service service = null;
try {
//获取应用的application对象
Application app = packageInfo.makeApplicationInner(false, mInstrumentation);
final java.lang.ClassLoader cl;
if (data.info.splitName != null) {
cl = packageInfo.getSplitClassLoader(data.info.splitName);
} else {
cl = packageInfo.getClassLoader();
}
//实例化一个服务对象
service = packageInfo.getAppFactory()
.instantiateService(cl, data.info.name, data.intent);
//服务的上下文
ContextImpl context = ContextImpl.getImpl(service
.createServiceBaseContext(this, packageInfo));
if (data.info.splitName != null) {
context = (ContextImpl) context.createContextForSplit(data.info.splitName);
}
if (data.info.attributionTags != null && data.info.attributionTags.length > 0) {
final String attributionTag = data.info.attributionTags[0];
context = (ContextImpl) context.createAttributionContext(attributionTag);
}
// 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);
//调用attach方法
service.attach(context, this, data.info.name, data.token, app,
ActivityManager.getService());
//调用onCreate方法
service.onCreate();
//数据存入map
mServicesData.put(data.token, data);
mServices.put(data.token, service);
try {
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
}
}
}
8.ProcessRecord.java
8.1.scheduleCrashLocked
void scheduleCrashLocked(String message, int exceptionTypeId, @Nullable Bundle extras) {
//
if (!mKilledByAm) {
if (mThread != null) {
if (mPid == Process.myPid()) {
//系统进程
return;
}
final long ident = Binder.clearCallingIdentity();
try {//见7.2.
mThread.scheduleCrash(message, exceptionTypeId, extras);
}
}
}
}
9.AppErrors.java
9.1.scheduleAppCrashLocked
引起给定的app崩溃
void scheduleAppCrashLocked(int uid, int initialPid, String packageName, int userId,
String message, boolean force, int exceptionTypeId, @Nullable Bundle extras) {
ProcessRecord proc = null;
//根据参数先查找到进程
synchronized (mService.mPidsSelfLocked) {
for (int i=0; i<mService.mPidsSelfLocked.size(); i++) {
ProcessRecord p = mService.mPidsSelfLocked.valueAt(i);
if (uid >= 0 && p.uid != uid) {
continue;
}
if (p.getPid() == initialPid) {
proc = p;
break;
}
if (p.getPkgList().containsKey(packageName)
&& (userId < 0 || p.userId == userId)) {
proc = p;
}
}
}
if (proc == null) {
//没找到进程
return;
}
//异常类型 是 adb异常
if (exceptionTypeId == CrashedByAdbException.TYPE_ID) {
String[] packages = proc.getPackageList();
for (int i = 0; i < packages.length; i++) {
if (mService.mPackageManagerInt.isPackageStateProtected(packages[i], proc.userId)) {
//pkg受保护
return;
}
}
}
//见8.1,计划崩溃
proc.scheduleCrashLocked(message, exceptionTypeId, extras);
if (force) {
//强制的话,过5秒杀死应用
final ProcessRecord p = proc;
mService.mHandler.postDelayed(
() -> {
synchronized (mService) {
synchronized (mProcLock) {
killAppImmediateLSP(p, ApplicationExitInfo.REASON_OTHER,
ApplicationExitInfo.SUBREASON_INVALID_STATE,
"forced", "killed for invalid state");
}
}
},
5000L);
}
}
10.ServiceRecord.java
- android:persistent 是一个用于控制应用程序特殊持久模式的标志。通常情况下不应被应用程序使用,它要求系统始终保持应用程序的运行。
10.1.getTracker
返回服务追踪器
public ServiceState getTracker() {
if (tracker != null) {
return tracker;
}
//非持久应用
if ((serviceInfo.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) == 0) {
//有旧的返回旧的,没有创建一个新的放入集合并返回
tracker = ams.mProcessStats.getServiceState(serviceInfo.packageName,
serviceInfo.applicationInfo.uid,
serviceInfo.applicationInfo.longVersionCode,
serviceInfo.processName, serviceInfo.name);
tracker.applyNewOwner(this);
}
return tracker;
}
10.2.postNotification
显示通知
public void postNotification() {
if (isForeground && foregroundNoti != null && app != null) {
final int appUid = appInfo.uid;
final int appPid = app.getPid();
final String localPackageName = packageName;
final int localForegroundId = foregroundId;
final Notification _foregroundNoti = foregroundNoti;
final ServiceRecord record = this;
ams.mHandler.post(new Runnable() {
public void run() {
NotificationManagerInternal nm = LocalServices.getService(
NotificationManagerInternal.class);
if (nm == null) {
return;
}
//通知权限检查
mFgsHasNotificationPermission = nm.areNotificationsEnabledForPackage(
localPackageName, appUid);
Notification localForegroundNoti = _foregroundNoti;
try {
if (localForegroundNoti.getSmallIcon() == null) {
//没有设置小图标的话,这里重新创建了一个通知,用的应用的icon
//..
localForegroundNoti = notiBuilder.build();
} catch (PackageManager.NameNotFoundException e) {
}
}
if (nm.getNotificationChannel(localPackageName, appUid,
localForegroundNoti.getChannelId()) == null) {
//channel id为空,抛出异常
}
if (localForegroundNoti.getSmallIcon() == null) {
//还是没有小图标,抛出异常
throw new RuntimeException("invalid service notification: "
+ foregroundNoti);
}
//通知插入队列
nm.enqueueNotification(localPackageName, localPackageName,
appUid, appPid, null, localForegroundId, localForegroundNoti,
userId);
foregroundNoti = localForegroundNoti; // save it for amending next time
//回调处理
signalForegroundServiceNotification(packageName, appInfo.uid,
localForegroundId, false /* canceling */);
}
}
});
}
}