[Android各版本特性]专栏目录:
01. Android API 版本对照表
02. Android 4.4以前版本特性
03. 为什么以Android4.4做分界线
04. Android 4.4 Kitkat
05. Android 5.0 Android Lollipop
06. Android 6.0 Marshmallow
07. Android 7.0 Nougat
08. Android 8.0 Oreo
09. Android 9.0 Pie
10. Android 10
11. 总结(推荐)
Android8.0版本调整了很多东西,特别要注意的是:
Android 8.0 允许以画中画 (PIP) 模式启动操作组件。PIP 是一种特殊的多窗口模式,最常用于视频播放。当某个 Activity 处于 PIP 模式时,它会处于暂停状态,但仍应继续显示内容。因此,您应确保您的应用在 onPause() 处理程序中进行处理时不会暂停播放。相反,您应在 onStop() 中暂停播放视频,并在 onStart() 中继续播放。
Android 8.0 和 Android 支持库 26 允许您从提供程序应用请求字体,而无需将字体绑定到 APK 中或让 APK 下载字体。此功能可减小 APK 大小,提高应用安装成功率,使多个应用可以共享同一种字体。
Android 8.0 推出一项新功能,即 XML 中的字体,允许您使用字体作为资源。这意味着,不再需要以资产的形式捆绑字体。字体在 R 文件中编译,并且作为一种资源,可自动用于系统。然后,您可以利用一种新的资源类型 font 来访问这些字体。
在运行 API 版本 14 及更高版本的设备中,支持库 26 对此功能提供完全支持。
Android 8.0 允许您根据 TextView 的大小自动设置文本展开或收缩的大小。这意味着,在不同屏幕上优化文本大小或者优化包含动态内容的文本大小比以往简单多了。
Android 8.0 引入自适应启动器图标。自适应图标支持视觉效果,可在不同设备型号上显示为各种不同的形状。
图像应用的 Android 开发者现在可以利用支持广色域彩色显示的新设备。要显示广色域图像,应用需要在其清单(每个操作组件)中启用一个标志,并加载具有嵌入的广域彩色配置文件(AdobeRGB、Pro Photo RGB、DCI-P3 等)的位图。
从 Android 8.0 开始,此平台为多显示器提供增强的支持。如果 Activity 支持多窗口模式,并且在具有多显示器的设备上运行,则用户可以将 Activity 从一个显示器移动到另一个显示器。当应用启动 Activity 时,此应用可指定 Activity 应在哪个显示器上运行。
Android 8.0 让您可以更轻松地指定 View 元素的对边使用相同外边距和内边距的情形。具体来说,您现在可以在布局 XML 文件中使用以下属性:
注意:请记住,这些属性不会影响 layout_marginStart、layout_marginEnd、paddingStart 或 paddingEnd 的值。您可以自行设置这些值和新的垂直与水平布局属性来创建取决于文本方向的布局行为。
从 Android 8.0 开始,AnimatorSet API 现在支持寻道和倒播功能。寻道功能允许您将动画的位置设置为指定的时间点处。如果您的应用包含可撤消的操作的动画,倒播功能会很有用。现在,您不必定义两组独立的动画,而只需反向播放同一组动画。
Android 8.0 优化了缓存数据的导航和行为。现在,每个应用均获得一定的磁盘空间配额,用于存储 getCacheQuotaBytes(UUID) 返回的缓存数据。
当系统需要释放磁盘空间时,将开始从超过配额最多的应用中删除缓存文件。因此,如果将您的缓存数据量始终保持低于配额的水平,则在必须清除系统中的某些文件时,您的缓存文件将能坚持到最后。系统在决定删除您的应用中的哪些缓存文件时,将首先考虑删除最旧的文件(由修改时间确定)。
您还可以针对每个目录启用两种新行为,以控制系统如何释放缓存数据:
最后,在需要为大文件分配磁盘空间时,可考虑使用新的 allocateBytes(FileDescriptor, long) API,它将自动清除属于其他应用的缓存文件(根据需要),以满足您的请求。在确定设备是否有足够的磁盘空间保存您的新数据时,请调用 getAllocatableBytes(UUID) 而不要使用 getUsableSpace(),因为前者会考虑系统要为您清除的任何缓存数据。
现在,ContentProvider 和 ContentResolver 类均包含 refresh() 函数,这样,客户端可以更轻松地知道所请求的信息是否为最新信息。
您可以扩展 ContentProvider 以添加自定义的内容刷新逻辑。请务必重写 refresh() 函数,以返回 true,告知提供程序的客户端您已尝试自行刷新数据。
您的客户端应用可通过调用另一个函数(又称 refresh()),显式请求已刷新的内容。在调用此函数时,传入待刷新数据的 URI。
注:由于您可能通过网络不断请求数据,您应仅在有明显迹象表明内容确已过时时才从客户端调用 refresh()。执行此类内容刷新最常见的原因是响应滑动刷新手势,该手势显式请求当前界面显示最新内容。
Android 8.0 引入了对 JobScheduler 的多项改进。由于您通常可以使用计划作业替代现在受限的后台服务或隐式广播接收器,这些改进可以让您的应用更轻松地符合新的后台执行限制。
JobScheduler 的更新包括:
您现在可以将工作队列与计划作业关联。要将一个工作项添加到作业的队列中,请调用 JobScheduler.enqueue()。当作业运行时,它可以将待定工作从队列中剥离并进行处理。这种功能可以处理之前需要启动后台服务(尤其是实现 IntentService 的服务)的许多用例。
您现在可以通过调用 JobInfo.Builder.setClipData() 的方式将 ClipData 与作业关联。利用此选项,您可以将 URI 权限授予与作业关联,类似于这些权限传递到 Context.startService() 的方式。您也可以将 URI 权限授予用于工作队列上的 intent。
计划作业现在支持多个新的约束条件:
您的服务可以使用 requestAudioFocus() 函数提交一个更精细的设备级音频焦点接收请求。传入一个 AudioFocusRequest 对象,您可以使用 AudioFocusRequest.Builder 创建这个对象。在这个构建类中,您可以指定以下选项:
注:构建您的 AudioFocusRequest 实例时,如果您通过调用 setAcceptsDelayedFocusGain() 指示您的服务可以等待产生声音,您也必须调用 setOnAudioFocusChangeListener(),以便您的服务了解它何时可以开始产生声音。
Android 8.0 通过增加以下功能,增强了平台对蓝牙的支持:
Android 8.0 引入了多个与电话有关的新权限:
这些权限均被划分为危险类别,属于 PHONE 权限组。
在 Android 8.0 之前,如果应用在运行时请求权限并且被授予该权限,系统会错误地将属于同一权限组并且在清单中注册的其他权限也一起授予应用。
对于针对 Android 8.0 的应用,此行为已被纠正。系统只会授予应用明确请求的权限。然而,一旦用户为应用授予某个权限,则所有后续对该权限组中权限的请求都将被自动批准。
Android 8.0 为提高电池续航时间而引入的变更之一是,当您的应用进入已缓存状态时,如果没有活动的组件,系统将解除应用具有的所有唤醒锁。
此外,为提高设备性能,系统会限制未在前台运行的应用的某些行为。具体而言:
默认情况下,这些限制仅适用于针对 O 的应用。不过,用户可以从 Settings 屏幕为任意应用启用这些限制,即使应用并不是以 O 为目标平台。
Android 8.0 还对特定函数做出了以下变更:
为节约电池电量、保持良好的用户体验和确保系统健康运行,在运行 Android 8.0 的设备上使用后台应用时,降低了后台应用接收位置更新的频率。此行为变更会影响包括 Google Play 服务在内的所有接收位置更新的应用。
Android 8.0 对网络连接和 HTTP(S) 连接行为做出了以下变更:
无正文的 OPTIONS 请求具有 Content-Length: 0 标头。之前,这些请求没有 Content-Length 标头。
HttpURLConnection 在包含斜线的主机或颁发机构名称后面附加一条斜线,使包含空路径的网址规范化。例如,它将 http://example.com 转化为 http://example.com/。
通过 ProxySelector.setDefault() 设置的自定义代理选择器仅针对所请求的网址(架构、主机和端口)。因此,仅可根据这些值选择代理。传递至自定义代理选择器的网址不包含所请求的网址的路径、查询参数或片段。
URI 不能包含空白标签。
之前,平台支持一种权宜方法,即允许主机名称中包含空白标签,但这是对 URI 的非法使用。此权宜方法只是为了确保与旧版 libcore 兼容。开发者如果对 API 使用不当,将会看到一条 ADB 消息:“URI example…com 的主机名包含空白标签。此格式不正确,将不被未来的 Android 版本所接受。”Android 8.0 废除了此权宜方法;系统对格式错误的 URI 会返回 null。
Android 8.0 在实现 HttpsURLConnection 时不会执行不安全的 TLS/SSL 协议版本回退。
对隧道 HTTP(S) 连接处理进行了如下变更:
在通过连接建立隧道 HTTP(S) 连接时,系统会在 Host 行中正确放置端口号 (:443) 并将此信息发送至中间服务器。之前,端口号仅出现在 CONNECT 行中。
系统不再将隧道连接请求中的 user-agent 和 proxy-authorization 标头发送至代理服务器。
在建立隧道时,系统不再将隧道 Http(s)URLConnection 中的 proxy-authorization 标头发送至代理。相反,由系统生成 proxy-authorization 标头,在代理响应初始请求发送 HTTP 407 后将其发送至此代理。
同样地,系统不再将 user-agent 标头由隧道连接请求复制到建立隧道的代理请求。相反,库为此请求生成 user-agent 标头。
如果之前执行的 connect() 函数失败,send(java.net.DatagramPacket) 函数将会引发 SocketException。
在回退到 TCP Echo 协议之前,InetAddress.isReachable() 会尝试执行 ICMP。