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
。
基于 Web 的数据目录按进程分开
为了提高 Android 9 中的应用稳定性和数据完整性,应用无法在多个进程之间共享单个WebView
数据目录。通常,此类数据目录存储 Cookie、HTTP 缓存以及与 Web 浏览相关的其他持久性和临时存储。
在大多数情况下,您的应用应仅在一个进程中使用android.webkit
包中的类,例如WebView
和CookieManager
。例如,您应将使用WebView
的所有Activity
对象移到同一个进程中。您可以通过在应用的其他进程中调用disableWebView()
来更严格地执行“仅限一个进程”规则。此调用可防止WebView
意外地在其他进程中初始化,即使它是从依赖库调用的。
如果您的应用必须在一个以上进程中使用WebView
的实例,则必须在使用给定WebView
实例之前,为每个进程分配唯一的数据目录后缀,方法是使用WebView.setDataDirectorySuffix()
方法。此方法将每个进程的 Web 数据放置在其应用数据目录中的自己的目录中。
每个应用的 SELinux 域
面向 Android 9 或更高版本的应用无法使用世界可访问的 Unix 权限与其他应用共享数据。此更改提高了Android 应用沙箱的完整性,特别是关于应用的私有数据只能由该应用访问的要求。
要与其他应用共享文件,请使用内容提供程序。
连接性变化
连接数据计数和多路径
在面向 Android 9 或更高版本的应用中,系统会计算非当前默认网络上的网络流量(例如,设备处于 Wi-Fi 状态下的蜂窝流量),并在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之类的实用程序),以避免与运行时提供的类出现类兼容性问题。
UI 更改
视图焦点
面积为 0 的视图(宽度或高度为 0)不再可聚焦。
此外,活动不再隐式分配触摸模式下的初始焦点。相反,您可以根据需要显式请求初始焦点。
CSS RGBA 十六进制值处理
面向 Android 9 或更高版本的应用必须启用处理 4 位和 8 位十六进制 CSS 颜色的草案CSS 颜色模块级别 4行为。
Chrome 自 52 版起就支持 CSS 颜色模块级别 4,但WebView目前禁用了此功能,因为发现现有的 Android 应用在 Android 排序 (ARGB) 中包含 32 位十六进制颜色,这会导致渲染错误。
例如,颜色#80ff8080
当前在面向 API 级别 27 或更低版本的应用的WebView中呈现为不透明的浅红色(#ff8080
)。前导组件(Android 将其解释为 alpha 组件)当前被忽略。如果应用面向 API 级别 28 或更高版本,则#80ff8080
将解释为 50% 透明的浅绿色(#80ff80
)。
针对 file: URI 的 MIME 类型嗅探
低于 Android 9 的 Android 版本可以从文件内容推断 MIME 类型。从 Android 9(API 级别 28)开始,应用在WebView中加载file:
URI 时必须使用正确的文件扩展名。
使用文件内容推断 MIME 类型可能是安全漏洞的来源,现代浏览器通常不允许这样做。
如果文件具有可识别的文件扩展名,例如.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 开始,挂起应用的通知会隐藏,直到应用恢复。