8.0Android知识我爱编程

Android O 功能新特性

2017-06-30  本文已影响177人  咻咻ing

Android O 除了提供诸多新特性和功能外,还对系统和 API 行为做出了各种变更。本文重点介绍您应该了解并在开发应用时加以考虑的一些主要变更。

其中大部分变更会影响所有应用,而不论应用针对的是何种版本的 Android。不过,有几项变更仅影响针对 Android O 的应用。为清楚起见,本页面分为两个部分:针对所有 API 级别的应用针对 Android O 的应用

针对所有 API 级别的应用


这些行为变更适用于 在 Android O 平台上运行的 所有应用,无论这些应用是针对哪个 API 级别构建。所有开发者都应查看这些变更,并修改其应用以正确支持这些变更(如果适用)。

后台执行限制

Android O 为提高电池寿命而引入的变更之一是,当您的应用进入已缓存状态时,如果没有活动的组件,系统将解除应用具有的所有唤醒锁。

Android 后台位置限制

为节约电池电量,保持良好的用户体验和确保系统健康运行,在运行 Android O 的设备上使用后台应用时,降低了后台应用接收位置更新的频率。此行为变更会影响包括 Google Play 服务在内的所有接收位置更新的应用。
此类变更会影响以下 API:

Android O 还对特定方法做出了以下变更:

为确保您的应用按预期方式运行,请完成以下步骤:

如需了解此类变更的详细信息,请参阅后台位置限制

蓝牙

Android O 对 ScanRecord.getBytes() 方法检索的数据长度做出了以下变更:

输入和导航

随着 Android 应用出现在 Chrome 操作系统和平板电脑等其他大尺寸设备上,我们看到,用户在 Android 应用中又重新开始使用键盘导航。在 Android O 中,我们又再次使用键盘作为导航输入设备,从而为基于箭头和标签的导航构建了一种更可靠并且可预测的模型。

如需了解如何在您的应用中改善对键盘导航的支持,请阅读支持键盘导航指南。

无障碍功能

现在,无障碍服务可识别应用的 TextView 对象内部的所有 ClickableSpan 实例。

如需了解有关如何让您的应用更便于访问的更多信息,请参阅无障碍功能

安全性

Android O 包含以下与安全性有关的变更:

有关提升应用安全性的其他准则,请参阅面向 Android 开发者的安全性

网络连接和 HTTP(S) 连接

Android O 对网络连接和 HTTP(S) 连接行为做出了以下变更:

记录未捕获的异常

如果某个应用安装的 Thread.UncaughtExceptionHandler 未移交给默认的 Thread.UncaughtExceptionHandler,则当出现未捕获的异常时,系统不会终止应用。从 Android O 开始,在此情况下系统将记录异常堆栈跟踪情况;在之前的平台版本中,系统不会记录异常堆栈跟踪情况。

我们建议,自定义 Thread.UncaughtExceptionHandler 实现始终移交给默认处理程序处理;遵循此建议的应用不受 Android O 此项变更的影响。

集合的处理

现在,AbstractCollection.removeAll()AbstractCollection.retainAll() 始终引发 NullPointerException;之前,当集合为空时不会引发 NullPointerException。此项变更使行为符合文档要求。

语言区域和国际化

Android 7.0(API 级别 24)引入能指定默认类别语言区域的概念,但是某些 API 在本应使用默认 DISPLAY
类别语言区域时,仍然使用不带参数的通用 Locale.getDefault() 方法。现在,在 Android O 中,以下方法使用 Locale.getDefault(Category.DISPLAY) 来代替 Locale.getDefault()

当为 Locale 参数指定的 displayScript 值不可用时,Locale.getDisplayScript(Locale) 同样回退到 Locale.getDefault()

与语言区域和国际化有关的其他变更如下:

联系人提供程序使用情况统计方法的变更

在之前版本的 Android 中,联系人提供程序组件允许开发者获取每个联系人的使用情况数据。此使用情况数据揭示了与某个联系人相关联的每个电子邮件地址和每个电话号码的信息,包括与该联系人联系的次数以及上次联系该联系人的时间。请求 READ_CONTACTS权限的应用可以读取此数据。

如果应用请求 READ_CONTACTS
权限,它们仍可以读取此数据。从 Android O 开始,使用情况数据查询会返回近似值,而不是精确值。不过,Android 系统内部仍然会保留精确值,因此,此变更不会影响 auto-complete API。

此行为变更会影响以下查询参数:
-TIMES_CONTACTED
-TIMES_USED
-LAST_TIME_CONTACTED
-LAST_TIME_USED

应用快捷键

Android O 对应用快捷键做出了以下变更:

如需了解有关应用快捷键变更的更多信息,请参阅固定快捷键和小部件预览功能指南

提醒窗口

如果应用使用 SYSTEM_ALERT_WINDOW 权限并且尝试使用以下窗口类型之一来在其他应用和系统窗口上方显示提醒窗口:

那么,这些窗口将始终显示在使用 TYPE_APPLICATION_OVERLAY 窗口类型的窗口下方。如果应用针对的是 Android O,则应用会使用 TYPE_APPLICATION_OVERLAY 窗口类型来显示提醒窗口。

如需了解详细信息,请参阅针对 Android O 的应用的行为变更内的提醒窗口的常用窗口类型部分。

企业中的 Android

Android O 包含会影响企业应用的变更。如果您正在为企业构建应用,包括 DPC(设备规范控制器),您应查阅企业中的 Android 页面中介绍的变更,并相应修改您的应用。

针对 Android O 的应用


这些行为变更专门应用于针对 O 平台或更高平台版本的应用。针对 Android O 或更高平台版本进行编译,或将 targetSdkVersion 设为 Android O 或更高版本的应用开发者必须修改其应用以正确支持这些行为(如果适用)。

后台执行限制

为提高设备性能,系统会限制未在前台运行的应用的某些行为。具体而言:

如需了解详细信息,请参阅后台执行限制

安全性

如果您的应用的网络安全性配置选择退出对明文流量的支持,那么,您的应用的 WebView 对象无法通过 HTTP 访问网站。每个 WebView 对象必须转而使用 HTTPS。

有关提升应用安全性的其他准则,请参阅面向 Android 开发者的安全性

隐私性

以下变更影响 Android O 的隐私性。

权限

在 Android O 之前,如果应用在运行时请求权限并且被授予该权限,系统会错误地将属于同一权限组并且在清单中注册的其他权限也一起授予应用。

对于针对 Android O 的应用,此行为已被纠正。系统只会授予应用明确请求的权限。然而,一旦用户为应用授予某个权限,则所有后续对该权限组中权限的请求都将被自动批准。

例如,假设某个应用在其清单中列出 READ_EXTERNAL_STORAGEWRITE_EXTERNAL_STORAGE。应用请求 READ_EXTERNAL_STORAGE,并且用户授予了该权限。如果该应用针对的是 API 级别 24 或更低级别,系统还会同时授予 WRITE_EXTERNAL_STORAGE,因为该权限也属于同一 STORAGE 权限组并且也在清单中注册过。如果该应用针对的是 Android O,则系统此时仅会授予 READ_EXTERNAL_STORAGE;不过,如果该应用后来又请求 WRITE_EXTERNAL_STORAGE,则系统会立即授予该权限,而不会提示用户。

媒体

原生库

在针对 Android O 的应用中,如果原生库包含任何可写且可执行的加载代码段,则不会再加载原生库。倘若某些应用的原生库包含不正确的加载代码段,则此变更可能会导致这些应用停止工作。这是一种安全加强措施。

如需了解详细信息,请参阅可写且可执行的代码段

与早期的开发者预览版相同,Android O 还有助于更轻松地发现所有与链接器有关的问
题。链接器的变更绑定到应用的目标 API 级别。如果应用的目标 API 级别发生链接器变更,则该应用无法加载该库。如果您的目标 API 级别低于发生链接器变更的 API 级别,则 logcat 会显示一条警告消息。在预览版期间,与链接器有关的问题不仅会显示在 logcat 中,也会以 toast 的形式显示。对于特定的 API 级别,警告可能会变成错误,此变更有助于提前发现此类问题。

集合的处理

在 Android O 中,Collections.sort() 是在 [List.sort()](https://developer.android.com/reference/java/util/List.html#sort(java.util.Comparator<? super E>)) 的基础上实现的。在 Android 7.x(API 级别 24 和 25)中,则恰恰相反。在过去,[List.sort()](https://developer.android.com/reference/java/util/List.html#sort(java.util.Comparator<? super E>)) 的默认实现会调用 Collections.sort()

此项变更使 Collections.sort() 可以利用优化的 [List.sort()](https://developer.android.com/reference/java/util/List.html#sort(java.util.Comparator<? super E>)) 实现,但具有以下限制:

@Override
public void sort(Comparator<? super E> c) {
  Object[] elements = toArray();
  Arrays.sort(elements, c);
  ListIterator<E> iterator = (ListIterator<Object>) listIterator();
  for (Object element : elements) {
    iterator.next();
    iterator.set((E) element);
  }
}

在大多数情况下,您也可以使用根据 API 级别委托给其他默认实现的实现重写 [List.sort()](https://developer.android.com/reference/java/util/List.html#sort(java.util.Comparator<? super E>))。例如:

@Override
public void sort(Comparator<? super E> comparator) {
  if (Build.VERSION.SDK_INT <= 25) {
    Collections.sort(this);
  } else {
    super.sort(comparator);
  }
}

如果您选择后者只是因为您希望开发一种适用于所有 API 级别的 sort() 方法,可以考虑赋予其一个唯一的名称,例如 sortCompat(),而不是重写 sort()。

帐号访问和可检测性

除非身份验证器拥有用户帐号或用户授予访问权限,否则,应用将无法再访问用户帐号。仅拥有 GET_ACCOUNTS 权限尚不足以访问用户帐号。要获得帐号访问权限,应用应使用 [AccountManager.newChooseAccountIntent()](https://developer.android.com/reference/android/accounts/AccountManager.html#newChooseAccountIntent(android.accounts.Account, java.util.List<android.accounts.Account>, java.lang.String[], java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle)) 或特定于身份验证器的方法。获得帐号访问权限后,应用可以调用 AccountManager.getAccounts() 来访问帐号。

Android O 已弃用 LOGIN_ACCOUNTS_CHANGED_ACTION。相反,应用在运行时应使用 [addOnAccountsUpdatedListener()](https://developer.android.com/reference/android/accounts/AccountManager.html#addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean)) 获取帐号更新信息。

有关新增 API 和增加的帐号访问和可检测性方法的信息,请参阅此文档的“新增 API”部分中的帐号访问和可检测性

提醒窗口

使用 SYSTEM_ALERT_WINDOW 权限的应用无法再使用以下窗口类型来在其他应用和系统窗口上方显示提醒窗口:

相反,应用必须使用名为 TYPE_APPLICATION_OVERLAY 的新窗口类型。
使用 TYPE_APPLICATION_OVERLAY 窗口类型显示应用的提醒窗口时,请记住新窗口类型的以下特性:

内容变更通知

Android O 更改了 [ContentResolver.notifyChange()](https://developer.android.com/reference/android/content/ContentResolver.html#notifyChange(android.net.Uri, android.database.ContentObserver)) 和 [registerContentObserver(Uri, boolean, ContentObserver)](https://developer.android.com/reference/android/content/ContentResolver.html#registerContentObserver(android.net.Uri, boolean, android.database.ContentObserver)) 在面向针对 Android O 的应用中的行为方式。

现在,这些 API 需要在所有 URI 中为颁发机构定义一个有效的 ContentProvider。使用相关权限定义一个有效的 ContentProvider 可帮助您的应用防范来自恶意应用的内容变更,并防止将可能的私密数据泄露给恶意应用。

欢迎关注个人公众号
上一篇下一篇

猜你喜欢

热点阅读