行为变更:以 API 级别 28 及更高级别为目标的应用

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 软件包中的类,例如 WebViewCookieManager。例如,您应将所有使用 WebViewActivity 对象移至同一进程。您可以通过在应用的其他进程中调用 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.scrollTopdocument.body.scrollLeftdocument.documentElement.scrollTopdocument.documentElement.scrollLeft 的行为因目标 SDK 而异。如需访问视口滚动值,请使用 document.scrollingElement(如果有)。

来自已暂停应用的通知

在 Android 9 之前,已暂停的应用发出的通知会被取消。从 Android 9 开始,已暂停的应用发出的通知将被隐藏,直到应用恢复运行。