Android 9(API 级别 28)对 Android 系统引入了多项变更。以下行为变更仅影响以 API 级别 28 或更高级别为目标的应用。将 targetSdkVersion
设为 API 级别 28 或更高级别的应用必须修改其应用,以正确支持这些行为(如果适用)。
如需了解会影响在 Android 9 上运行的所有应用的变更(无论这些应用以哪个 API 级别为目标平台),请参阅行为变更:所有应用。
前台服务
以 Android 9 或更高版本为目标平台并使用前台服务的应用必须请求 FOREGROUND_SERVICE
权限。这是普通权限,因此,系统会自动为请求权限的应用授予此权限。
如果以 Android 9 或更高版本为目标平台的应用尝试在未请求 FOREGROUND_SERVICE
的情况下创建前台服务,系统会抛出 SecurityException
。
隐私权变更
如果您的应用以 Android 9 为目标平台,您应牢记以下行为变更。对设备序列信息和 DNS 信息进行的这些更新可增强用户隐私保护。
构建序列号弃用
在 Android 9 中,Build.SERIAL
始终设置为 "UNKNOWN"
以保护用户的隐私。
如果您的应用需要访问设备的硬件序列号,您应改为请求 READ_PHONE_STATE
权限,然后调用 getSerial()
。
DNS 隐私权
以 Android 9 为目标平台的应用应支持专用 DNS API。具体而言,应用应确保,如果系统解析器正在执行 DNS-over-TLS,则任何内置 DNS 客户端要么使用加密 DNS 访问与系统相同的主机名,要么停用,取而代之的是系统解析器。
框架安全性变更
Android 9 包含多项可提升应用安全性的行为变更,但仅当您的应用以 API 级别 28 或更高级别为目标平台时,这些变更才会生效。
默认启用网络传输层安全协议 (TLS)
如果您的应用以 Android 9 或更高版本为目标平台,isCleartextTrafficPermitted()
方法会默认返回 false
。如果您的应用需要为特定网域启用明文,您必须在应用的网络安全配置中针对这些网域将 cleartextTrafficPermitted
明确设置为 true
。
按进程分设基于网络的数据目录
为了提高 Android 9 中的应用稳定性和数据完整性,应用不能在多个进程之间共享单个 WebView
数据目录。通常,此类数据目录会存储 Cookie、HTTP 缓存以及其他与网页浏览相关的永久性和临时性存储空间。
在大多数情况下,您的应用只应在一个进程中使用 android.webkit
软件包中的类,例如 WebView
和 CookieManager
。例如,您应将所有使用 WebView
的 Activity
对象移至同一进程。您可以通过在应用的其他进程中调用 disableWebView()
来更严格地执行“仅限一个进程”规则。此调用可防止 WebView
在这些其他进程中被错误地初始化,即使从依赖库调用它也是如此。
如果您的应用必须在多个进程中使用 WebView
的实例,则必须先使用 WebView.setDataDirectorySuffix()
方法为每个进程分配一个唯一的数据目录后缀,然后再在该进程中使用 WebView
的给定实例。此方法会将每个进程的网络数据存储在应用数据目录内其自己的目录中。
按应用划分的 SELinux 域
以 Android 9 或更高版本为目标平台的应用无法使用可所有人访问的 Unix 权限与其他应用共享数据。此变更可提高 Android 应用沙盒的完整性,尤其是针对应用的私有数据只能由该应用访问这一要求。
如需与其他应用共享文件,请使用 content provider。
网络连接变更
网络连接数据计数和多路径
在以 Android 9 或更高版本为目标平台的应用中,系统会统计并非当前默认网络的网络流量(例如,当设备连接到 WLAN 时的移动网络流量),并在 NetworkStatsManager
类中提供查询该流量的方法。
具体而言,getMultipathPreference()
现在会返回基于上述网络流量的值。从 Android 9 开始,此方法会针对移动数据网络返回 true
,但当一天内累积的流量超过特定数量时,它会开始返回 false
。在 Android 9 上运行的应用必须调用该方法并遵循此提示。
ConnectivityManager.NetworkCallback
类现在会将有关 VPN 的信息发送到应用。此更改使应用能够更轻松地监听连接事件,而无需混合使用同步和异步调用,也不必使用有限的 API。此外,这也意味着当设备同时连接到多个 Wi-Fi 网络或多个移动网络时,信息传输会按预期运行。
Apache HTTP 客户端弃用
在 Android 6.0 中,我们取消了对 Apache HTTP 客户端的支持。从 Android 9 开始,默认情况下,该库已从 bootclasspath 中移除,并且不适用于应用。
如需继续使用 Apache HTTP 客户端,以 Android 9 及更高版本为目标平台的应用可以将以下内容添加到其 AndroidManifest.xml
中:
<uses-library android:name="org.apache.http.legacy" android:required="false"/>
作为使用运行时 Apache 库的替代方案,应用可以在其 APK 中捆绑自己的 org.apache.http
库版本。如果这样做,您必须重新打包库(使用 Jar Jar 等实用程序),以免运行时中提供的类出现类兼容性问题。
界面变更
视图焦点
0 面积的视图(即宽度或高度为 0)再也不能被聚焦。
此外,activity 在触摸模式下不再隐式分配初始焦点。而是由您根据需要显式请求初始焦点。
CSS RGBA 十六进制值处理
以 Android 9 或更高版本为目标平台的应用必须支持草稿 CSS 颜色模块级别 4 行为,以便处理 4 位和 8 位十六进制数字 CSS 颜色。
Chrome 自版本 52 起就支持 CSS 颜色模块级别 4,但 WebView 目前停用了该功能,因为我们发现现有 Android 应用包含 Android 排序 (ARGB) 中的 32 位十六进制颜色,这会导致呈现错误。
例如,对于以 API 级别 27 或更低级别为目标平台的应用,颜色 #80ff8080
目前在 WebView 中呈现为不透明浅红色 (#ff8080
)。先导部分(Android 会将其解读为 Alpha 部分)目前会被忽略。如果应用以 API 级别 28 或更高级别为目标平台,则 #80ff8080
会被解读为 50% 透明浅绿 (#80ff80
)。
文件的 MIME 类型嗅探:URI
Android 9 之前的 Android 版本可以根据文件内容推断 MIME 类型。从 Android 9(API 级别 28)开始,在 WebView 中加载 file:
URI 时,应用必须使用正确的文件扩展名。
使用文件内容推断 MIME 类型可能会导致安全 bug,现代浏览器通常不允许这样做。
如果文件具有可识别的文件扩展名(例如 .html
、.txt
、.js
或 .css
),MIME 类型将由扩展名决定。如果文件没有扩展名或扩展名无法识别,则 MIME 类型将为纯文本。
例如,file:///sdcard/test.html
等 URI 将呈现为 HTML 格式,但 file:///sdcard/test
等 URI 将呈现为纯文本,即使文件包含 HTML 数据也是如此。
文档滚动元素
Android 9 可正确处理文档的根元素是滚动元素的情况。在早期版本中,滚动位置在 body 元素上设置,根元素的滚动值为零。Android 9 支持符合标准的行为,在这种行为中,滚动元素是根元素。
此外,直接访问 document.body.scrollTop
、document.body.scrollLeft
、document.documentElement.scrollTop
或 document.documentElement.scrollLeft
的行为会因目标 SDK 而异。如需访问视口滚动值,请使用 document.scrollingElement
(如果有)。
来自已暂停应用的通知
在 Android 9 之前,已暂停的应用发出的通知会被取消。从 Android 9 开始,已暂停的应用发出的通知将被隐藏,直到应用恢复运行。