首先对我的回答做一点免责声明:
我的回答是基于 AOSP 代码,可能会因版本或制造商而异。
此外,我们或许可以推断制造商对其行为方式有发言权:
每个制造商都可以设置自己的标准来确定非活跃应用的方式
分配给存储桶。你不应该试图影响哪个桶
您的应用程序被分配到。相反,专注于确保您的应用
在任何可能的存储桶中都表现良好。您的应用程序可以找到
通过调用新方法,它当前在哪个桶中
UsageStatsManager.getAppStandbyBucket()。
作业将无法运行(有或没有充电器)
如果您查看 QuotaController,这是实现作业的存储桶限制的地方:
frameworks/base/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java
您会看到 NEVER_INDEX 只是关闭了作业可用性,并且不会隐式地继续/升级到更好的存储桶,除非某些东西会显式更改存储桶(例如,启动活动)。
这也适用于连接充电器时,如您在 isWithinQuotaLocked() 中所见:
if (standbyBucket == NEVER_INDEX) return false;
// Quota constraint is not enforced while charging.
if (mChargeTracker.isCharging()) {
// Restricted jobs require additional constraints when charging, so don't immediately
// mark quota as free when charging.
if (standbyBucket != RESTRICTED_INDEX) {
return true;
}
警报不会运行(有或没有充电器)
看看AlarmManagerService:
frameworks/base/services/core/java/com/android/server/AlarmManagerService.java
在那里,您可以看到在连接/断开充电器时调用了 reorderAlarmsBasedOnStandbyBuckets()。
它根据配额对警报重新排序,对于存储桶,它永远不会为 0。
private final int[] DEFAULT_APP_STANDBY_QUOTAS = {
720, // Active
10, // Working
2, // Frequent
1, // Rare
0 // Never
};
代码延迟了一天,直到超过 0:
if (quotaForBucket <= 0) {
// Just keep deferring for a day till the quota changes
minElapsed = mInjector.getElapsedRealtime() + MILLIS_IN_DAY;
}
网络无法在后台运行
因为没有可用的作业和警报,所以没有可以使用网络的端点。
只有当前台服务/活动将备用存储桶更改为文档中所写的活动时,它才会开始工作:
如果用户当前正在使用该应用,则该应用位于活动存储桶中
或最近使用该应用程序。例如: • 该应用程序启动了一个
活动 • 应用程序正在运行前台服务 • 应用程序具有
与前台使用的内容提供者关联的同步适配器
应用 • 用户点击来自应用的通知