Android 服务的限制

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 服务的限制相关的知识,希望对你有一定的参考价值。

参考技术A

Google官网将android服务分为了三种,前台服务,后台服务和绑定服务:

前台服务执行一些用户能注意到的操作。例如,音频应用会使用前台服务来播放音频曲目。前台服务必须显示 通知 。即使用户停止与应用的交互,前台服务仍会继续运行。

后台服务执行用户不会直接注意到的操作。例如,如果应用使用某个服务来压缩其存储空间,则此服务通常是后台服务。

当应用组件通过调用 bindService() 绑定到服务时,服务即处于 绑定 状态。绑定服务会提供客户端-服务器接口,以便组件与服务进行交互、发送请求、接收结果,甚至是利用进程间通信 (IPC) 跨进程执行这些操作。仅当与另一个应用组件绑定时,绑定服务才会运行。多个组件可同时绑定到该服务,但全部取消绑定后,该服务即会被销毁。

我个人理解服务可以分为两种, 前台 和 后台 ,而 绑定 应该是被当作一种状态,因为 前台服务 和 后台服务 都可以进行绑定。

基于这个理解,我们将限制分成了前台和后台两个部分:

从 Android 5.0(API 级别 21)开始,如果使用隐式 Intent 调用 bindService() ,则系统会抛出异常。为确保应用的安全性,在启动 Service 时,请始终使用显式 Intent,且不要为服务声明 Intent 过滤器。

在后台中运行的 Service 会消耗设备资源,这可能会降低用户体验。 为了缓解这一问题,系统对这些 Service 施加了一些限制。

处于前台时,应用可以自由创建和运行前台与后台 Service。

Android 8.0 开始:系统不允许后台应用创建后台 Service。否则该函数将引发一个 IllegalStateException。

Android 8.0 开始:进入后台时,在一个持续数分钟的时间窗内,应用仍可以创建和使用 Service。 在该时间窗结束后,应用将被视为处于 空闲 状态。 此时,系统将停止应用的后台 Service,就像应用已经调用 Service 的 Service.stopSelf() 方法一样。

为了解除这种限制,可以使用 JobScheduler 作业替换后台 Service。

在 Android 8.0 之前,创建前台 Service 的方式通常是先创建一个后台 Service,然后将该 Service 推到前台。

而在Android 8.0 之后,系统不允许后台应用创建后台 Service。

解决方案:调用 startForegroundService() ,以在前台启动新 Service。

在系统创建 Service 后,应用有五秒的时间来调用该 Service 的 startForeground() 方法以显示新 Service 的用户可见通知。 如果应用在此时间限制内 未 调用 startForeground() ,则系统将停止此 Service 并声明此应用为 ANR 。

前台服务必须显示优先级为 PRIORITY_LOW 或更高的 状态栏通知 ,这有助于确保用户知道应用正在执行的任务。如果某操作不是特别重要,因而您希望使用最低优先级通知,则可能不适合使用服务;相反,您可以考虑使用 计划作业 。

在 Android 9 (API 28)之后,使用前台服务必须申请 FOREGROUND_SERVICE 权限,否则会报 SecurityException 。 这是普通权限,因此,系统会自动为请求权限的应用授予此权限。

每个运行服务的应用都会给系统带来额外负担,从而消耗系统资源。如果应用尝试使用低优先级通知隐藏其服务,则可能会降低用户正在主动交互的应用的性能。因此,如果某个应用尝试运行拥有最低优先级通知的服务,则系统会在抽屉式通知栏的底部调用出该应用的行为。

以 Android 12 为目标平台的应用在后台运行时无法再启动 前台服务 。

Android 11 及以后,系统对前台服务何时可以访问设备的位置、摄像头或麦克风进行了限制。

如果您的应用以 Android 11 或更高版本为目标平台,且在前台服务中访问摄像头或麦克风,则必须添加 前台服务类型 camera 和 microphone 。

如果你的应用 在后台运行时启动了某项前台服务 :

如果某服务的功能(位置、麦克风 和 相机)受到了限制,则Logcat中会打印如下语句:

Android 用户通知中的注册 ID 限制

【中文标题】Android 用户通知中的注册 ID 限制【英文标题】:Registration ID limit in User Notifications of Android 【发布时间】:2015-04-22 12:51:02 【问题描述】:

重新安装或升级应用时,会从 GCM 服务器获取 gcm 注册 ID。当这个 id 添加到 User Notification Key 时,它会是 20 个注册 id 限制的一部分,还是服务器应该注销旧 id 并添加新 id?

【问题讨论】:

【参考方案1】:

一旦 GCM 服务器发布了新的注册 ID,您就可以用它覆盖旧的注册 ID。没有必要再保留旧的了。事实上,您不应该再使用旧的来发送推送通知。如果这样做,它仍然可以工作,但您将在 JSON 响应中返回一个规范 ID。该 ID 是您应该使用的设备的最新注册 ID。看看这里的规范 ID 部分: http://developer.android.com/google/gcm/gcm.html#reg

【讨论】:

对于用户通知,文档 link 说它只会在失败的情况下给出计数,而不是规范 id。我怎么知道哪个 id 失败了? 如果失败,它将返回失败的注册 ID 的数量和注册 ID 本身(查看相同的链接)。这是 JSON 格式: "success":1, "failure":2, "failed_registration_ids":[ "regId1", "regId2" ] failed_registration_ids 数组包含所有失败的注册 ID。如果您在此处获得任何 ID,则可以安全地从您的服务器中删除它们。这些用户很可能卸载了您的应用。如果他们重新安装,应用程序将重新注册他们,他们将获得新的注册 ID。【参考方案2】:

由于用户通知与 GCM 客户端注册的功能不同,因此您需要 remove 附加到此“用户通知密钥”的较早的 RegistrationId,然后使用新的 RegistrationId 调用 add。

【讨论】:

我如何知道要删除哪个 id?规范 id 不会有该映射。我应该在我的服务器上的数据库中将注册 ID 与设备 ID 映射吗?

以上是关于Android 服务的限制的主要内容,如果未能解决你的问题,请参考以下文章

Android - 服务器无法处理您的 apk - 大小限制?

android 一个程序可以启动多少个服务

仅将 API URL 限制为 Android 应用程序

android 12+从后台启动FGS限制

Android 用户通知中的注册 ID 限制

如何限制用户使用我的颤振 android 应用程序的有限服务期限?罗