Android 8.0 除了提供诸多新特性和功能外,还对系统和 API 行为做出了各种变更。本文重点介绍您应该了解并在开发应用时加以考虑的一些主要变更。
其中大部分变更会影响所有应用,而不论应用针对的是何种版本的 Android。不过,有几项变更仅影响针对 Android 8.0 的应用。为清楚起见,本页面分为两个部分:针对所有 API 级别的应用和针对 Android 8.0 的应用。
针对所有API级别的应用
后台执行限制
Android 8.0 为提高电池续航时间而引入的变更之一是,当您的应用进入已缓存状态时,如果没有活动的组件,系统将解除应用具有的所有唤醒锁。
此外,为提高设备性能,系统会限制未在前台运行的应用的某些行为。具体而言:
- 现在,在后台运行的应用对后台服务的访问受到限制。
- 应用无法使用其清单注册大部分隐式广播(即,并非专门针对此应用的广播)。
默认情况下,这些限制仅适用于针对 O 的应用。不过,用户可以从 Settings 屏幕为任意应用启用这些限制,即使应用并不是以 O 为目标平台。
Android 8.0 还对特定函数做出了以下变更:
- 如果针对 Android 8.0 的应用尝试在不允许其创建后台服务的情况下使用
startService()
函数,则该函数将引发一个IllegalStateException
。 - 新的
Context.startForegroundService()
函数将启动一个前台服务。现在,即使应用在后台运行,系统也允许其调用Context.startForegroundService()
。不过,应用必须在创建服务后的五秒内调用该服务的startForeground()
函数。
如需了解详细信息,请参阅后台执行限制。
android 后台位置限制
为节约电池电量、保持良好的用户体验和确保系统健康运行,在运行 Android 8.0 的设备上使用后台应用时,降低了后台应用接收位置更新的频率。此行为变更会影响包括 Google Play 服务在内的所有接收位置更新的应用。
此类变更会影响以下 API:
- Fused Location Provider (FLP)
- Geofencing
- GNSS Measurements
- Location Manager
- Wi-Fi Manager
为确保您的应用按预期方式运行,请完成以下步骤:
- 查看您的应用的逻辑,并确保您使用的是最新的位置 API。
- 测试您的应用是否在每个用例中都表现出预期行为。
- 考虑使用 Fused Location Provider (FLP) 或地理围栏来处理依赖于用户当前位置的用例。
如需了解此类变更的详细信息,请参阅后台位置限制。
提醒窗口
如果应用使用 SYSTEM_ALERT_WINDOW
权限并且尝试使用以下窗口类型之一来在其他应用和系统窗口上方显示提醒窗口:
...那么,这些窗口将始终显示在使用 TYPE_APPLICATION_OVERLAY
窗口类型的窗口下方。如果应用针对的是 Android 8.0,则应用会使用 TYPE_APPLICATION_OVERLAY
窗口类型来显示提醒窗口。
如需了解详细信息,请参阅针对 Android 8.0 的应用的行为变更内的提醒窗口的常用窗口类型部分。
联系人提供程序使用情况统计方法的变更
在之前版本的 Android 中,联系人提供程序组件允许开发者获取每个联系人的使用情况数据。此使用情况数据揭示了与某个联系人相关联的每个电子邮件地址和每个电话号码的信息,包括与该联系人联系的次数以及上次联系该联系人的时间。请求 READ_CONTACTS
权限的应用可以读取此数据。
如果应用请求 READ_CONTACTS
权限,它们仍可以读取此数据。从 Android 8.0 开始,使用情况数据查询会返回近似值,而不是精确值。不过,Android 系统内部仍然会保留精确值,因此,此变更不会影响 auto-complete API。
此行为变更会影响以下查询参数:
针对android 8.0的应用
这些行为变更专门应用于针对 O 平台或更高平台版本的应用。针对 Android 8.0 或更高平台版本进行编译,或将 targetSdkVersion
设为 Android 8.0 或更高版本的应用开发者必须修改其应用以正确支持这些行为(如果适用)。
提醒窗口
使用 SYSTEM_ALERT_WINDOW
权限的应用无法再使用以下窗口类型来在其他应用和系统窗口上方显示提醒窗口:
相反,应用必须使用名为 TYPE_APPLICATION_OVERLAY
的新窗口类型。
使用 TYPE_APPLICATION_OVERLAY
窗口类型显示应用的提醒窗口时,请记住新窗口类型的以下特性:
- 应用的提醒窗口始终显示在状态栏和输入法等关键系统窗口的下面。
- 系统可以移动使用
TYPE_APPLICATION_OVERLAY
窗口类型的窗口或调整其大小,以改善屏幕显示效果。 - 通过打开通知栏,用户可以访问设置来阻止应用显示使用
TYPE_APPLICATION_OVERLAY
窗口类型显示的提醒窗口。
视图焦点
可点击的 View
对象现在默认也可以成为焦点。如果您希望 View
对象可点击但不可成为焦点,请在包含 View
的布局 XML 文件中将 android:focusable
属性设置为 false
,或者将 false
传递至应用界面逻辑中的 setFocusable()
。
账号访问和可检测性
除非身份验证器拥有用户帐号或用户授予访问权限,否则,应用将无法再访问用户帐号。仅拥有 GET_ACCOUNTS
权限尚不足以访问用户帐号。要获得帐号访问权限,应用应使用 AccountManager.newChooseAccountIntent()
或特定于身份验证器的函数。获得帐号访问权限后,应用可以调用 AccountManager.getAccounts()
来访问帐号。
Android 8.0 已弃用 LOGIN_ACCOUNTS_CHANGED_ACTION
。相反,应用在运行时应使用 addOnAccountsUpdatedListener()
获取帐号更新信息。
有关新增 API 和增加的帐号访问和可检测性函数的信息,请参阅此文档的“新增 API”部分中的帐号访问和可检测性。
权限
在 Android 8.0 之前,如果应用在运行时请求权限并且被授予该权限,系统会错误地将属于同一权限组并且在清单中注册的其他权限也一起授予应用。
对于针对 Android 8.0 的应用,此行为已被纠正。系统只会授予应用明确请求的权限。然而,一旦用户为应用授予某个权限,则所有后续对该权限组中权限的请求都将被自动批准。
例如,假设某个应用在其清单中列出 READ_EXTERNAL_STORAGE
和 WRITE_EXTERNAL_STORAGE
。应用请求 READ_EXTERNAL_STORAGE
,并且用户授予了该权限。如果该应用针对的是 API 级别 24 或更低级别,系统还会同时授予 WRITE_EXTERNAL_STORAGE
,因为该权限也属于同一 STORAGE
权限组并且也在清单中注册过。如果该应用针对的是 Android 8.0,则系统此时仅会授予 READ_EXTERNAL_STORAGE
;不过,如果该应用后来又请求 WRITE_EXTERNAL_STORAGE
,则系统会立即授予该权限,而不会提示用户。
参考文档
https://developer.android.com/about/versions/oreo/android-8.0-changes