red*_*man 2 android android-source
从 Android 9 开始,如果从后台调用,它会抛出IllegalStateException。我在开发者控制台中多次看到此异常:startService()
java.lang.IllegalStateException:
at android.app.ContextImpl.startServiceCommon (ContextImpl.java:1666)
at android.app.ContextImpl.startService (ContextImpl.java:1611)
Run Code Online (Sandbox Code Playgroud)
在这些情况下,Google 建议改为startForegroundService()在 5 秒内致电 and startForeground()。请参阅“后台执行限制”。
无论如何,startService()从前台调用是完全可以的。现在,我想知道 Android 究竟是如何识别/决定应用程序位于前台而不错误地抛出 IllegalStateException的?
我开始挖掘Android9/10的源代码,并将其与8/7进行比较,以发现如何startService()修改以识别它是否是从前台/后台调用的。但我确信在我之前的许多开发人员已经这样做了,如果他们能够给出答案,我会很高兴。
在 AOSP10 (10.0.0_r25) 中:
服务器端:
在frameworks\base\services\core\java\com\android\server\am\ActiveServices.java的startServiceLocked中:
// Before going further -- if this app is not allowed to start services in the
// background, then at this point we aren't going to let it period.
final int allowed = mAm.getAppStartModeLocked(r.appInfo.uid, r.packageName,
r.appInfo.targetSdkVersion, callingPid, false, false, forcedStandby);
if (allowed != ActivityManager.APP_START_MODE_NORMAL) {
Slog.w(TAG, "Background start not allowed: service "
+ service + " to " + r.shortInstanceName
+ " from pid=" + callingPid + " uid=" + callingUid
+ " pkg=" + callingPackage + " startFg?=" + fgRequired);
......
// This app knows it is in the new model where this operation is not
// allowed, so tell it what has happened.
UidRecord uidRec = mAm.mProcessList.getUidRecordLocked(r.appInfo.uid);
return new ComponentName("?", "app is in background uid " + uidRec);
}
Run Code Online (Sandbox Code Playgroud)
然后在客户端:
在 ContextImpl.java 中作为日志:
else if (cn.getPackageName().equals("?")) {
throw new IllegalStateException(
"Not allowed to start service " + service + ": " + cn.getClassName());
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1163 次 |
| 最近记录: |