Android 8.1 功能和 API

Android 8.1(API 级别 27)引入了各种 为用户和开发者提供新功能。 本文重点介绍面向开发者的新功能。

Android Oreo(Go 版本)

Android Go 是一项旨在为全球数十亿网络用户优化 Android 体验的计划。从 Android 8.1 开始 我们正努力将 Android 打造成适合入门级设备的理想平台。Android Oreo(Go 版本)配置中的功能包括:

  • 内存优化。改进了整个平台的内存使用情况,可确保应用可以在内存不超过 1GB 的设备上高效运行。
  • 灵活的定位选项。新 硬件功能 常量,以便您可以通过 Google Play。
  • Google Play:所有应用都可以在搭载 Android Oreo 的设备上下载 (Go 版本),Google Play 将展示由开发者专门优化的应用 为数十亿人提供卓越体验,为数十亿人打造 指南。

我们为数十亿用户更新了建筑 指南中提供了额外的指南, 针对搭载 Android 系统的设备 Android Oreo(Go 版本)。对于大多数开发者来说,优化现有的 APK,或使用 Google Play 的多 APK 功能将某个 APK 版本定位到低内存设备,是针对搭载 Android Oreo(Go 版本)的设备做好准备的最佳方式。请注意,无论您的受众使用何种设备,将应用打造得更加纤巧高效都对他们有益。

Neural Networks API

Neural Networks API 为设备上的机器学习框架提供加速计算和推理功能,这些机器学习框架包括 TensorFlow Lite(Google 面向移动设备推出的跨平台机器学习内容库)以及 Caffe2,等等。如需获取下载内容和文档,请访问 TensorFlow Lite 开源代码库。TensorFlow Lite 与 Neural Networks API 配合使用,以运行 MobileNetsInception v3、 和 在移动设备上高效智能回复

自动填充框架更新

Android 8.1(API 级别 27)对自动填充框架进行了多项改进,您可以将这些改进整合到您的应用中。

BaseAdapter 类现在包含 setAutofillOptions() 方法,通过该方法,您可以在适配器中提供字符串形式的值。这对于显示旋转图标非常有用 在其适配器中动态生成值的控件。例如,您可以使用 setAutofillOptions() 方法提供字符串形式的年份列表,供用户选择信用卡失效日期时使用。自动填充服务可以使用字符串表示法 以适当方式填充需要数据的视图。

此外,AutofillManager 类还包含 notifyViewVisibilityChanged(View, int, boolean) 方法,当采用虚拟结构的视图的可见性发生改变时,您可以调用该方法来通知框架。对于非 虚拟结构。不过,非虚拟结构通常不要求您 并明确通知框架,因为 View 类。

Android 8.1 还通过在 SaveInfo 中添加对 CustomDescription and Validator 的支持,让自动填充服务能够更灵活地自定义保存界面功能。

自定义说明可帮助自动填充服务说明正在保存的内容。例如,当界面包含信用卡时,它可以显示信用卡发卡行的徽标、信用卡号码的最后四位数以及信用卡的失效日期。如需了解详情,请参阅 CustomDescription 类。

Validator 对象用于避免在验证器出现时显示自动填充保存界面 条件。如需了解详情,请参阅 Validator 类及其子类 LuhnChecksumValidatorRegexValidator

通知

Android 8.1 针对通知做了以下更改:

EditText 更新

从 API 级别 27 开始,EditText.getText() 方法会返回 Editable;之前,它会返回 CharSequence。此次变更 向后兼容,因为 Editable 会实现 CharSequence

Editable 接口提供重要的附加功能。例如,由于 Editable 还实现了 Spannable 接口,因此您可以对 EditText 实例中的内容应用标记。

程序化安全浏览操作

通过使用 Safe Browsing API 的 WebView 实现,您的应用可以检测 WebView 实例何时尝试转到 Google 已归类为已知威胁的网址。默认情况下,WebView 会显示一个插页,以警告用户存在已知威胁。通过该屏幕,用户可以选择仍然加载网址或返回到 返回上一页。

在 Android 8.1 中,您可以通过编程方式定义 对已知威胁做出响应:

  • 您可以控制应用是否向安全浏览功能报告已知威胁。
  • 您可以让应用在每次遇到被安全浏览功能归类为已知威胁的网址时,都自动执行特定操作(例如返回安全的页面)。

注意:为了防范已知威胁,请耐心等候 您必须先初始化安全浏览功能,然后再调用 WebView 对象的 loadUrl() 方法。

以下代码段展示了如何指示应用的 在遇到危险事件后,WebView一律返回安全状态 已知威胁:

AndroidManifest.xml

<manifest>
    <application>
        ...
        <meta-data android:name="android.webkit.WebView.EnableSafeBrowsing"
                   android:valu>e=&qu<ot;true">;< /
    /a>pplication
/manifest

MyWebActivity.java

Kotlin

private var superSafeWebView: WebView? = null
private var safeBrowsingIsInitialized: Boolean = false

// ...

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    superSafeWebView = WebView(this).apply {
        webViewClient = MyWebViewClient()
        safeBrowsingIsInitialized = false
        startSafeBrowsing(this@SafeBrowsingActivity, { success ->
            safeBrowsingIsInitialized = true
            if (!success) {
                Log.e("MY_APP_TAG", "Unable to initialize Safe Browsing!")
            }
        })
    }
}

Java

private WebView superSafeWebView;
private boolean safeBrowsingIsInitialized;

// ...

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    superSafeWebView = new WebView(this);
    superSafeWebView.setWebViewClient(new MyWebViewClient());
    safeBrowsingIsInitialized = false;

    superSafeWebView.startSafeBrowsing(this, new ValueCallback<Boolean>() {
        @Override
        public void onReceiveValue(Boolean success) {
            safeBrowsingIsInitialized = true;
            if (!success) {
                Log.e("MY_APP_TAG", "Unable to initialize Safe Browsing!");
            }
        }
    });
}

MyWebViewClient.java

Kotlin

class MyWebViewClient : WebViewClient() {
    // Automatically go "back to safety" when attempting to load a website that
    // Safe Browsing has identified as a known threat. An instance of WebView
    // calls this method only after Safe Browsing is initialized, so there's no
    // conditional logic needed here.
    override fun onSafeBrowsingHit(
            view: WebView,
            request: WebResourceRequest,
            threatType: Int,
            callback: SafeBrowsingResponse
    ) {
        // The "true" argument indicates that your app reports incidents like
        // this one to Safe Browsing.
        callback.backToSafety(true)
        Toast.makeText(view.context, "Unsafe web page blocked.", Toast.LENGTH_LONG).show()
    }
}

Java

public class MyWebViewClient extends WebViewClient {
    // Automatically go "back to safety" when attempting to load a website that
    // Safe Browsing has identified as a known threat. An instance of WebView
    // calls this method only after Safe Browsing is initialized, so there's no
    // conditional logic needed here.
    @Override
    public void onSafeBrowsingHit(WebView view, WebResourceRequest request,
            int threatType, SafeBrowsingResponse callback) {
        // The "true" argument indicates that your app reports incidents like
        // this one to Safe Browsing.
        callback.backToSafety(true);
        Toast.makeText(view.getContext(), "Unsafe web page blocked.",
                Toast.LENGTH_LONG).show();
    }
}

视频缩略图提取器

MediaMetadataRetriever 类新增了 getScaledFrameAtTime() 方法,该方法能够在给定时间值附近找到一个帧,并返回一个与源帧具有相同宽高比的位图,但会对该位图进行缩放,使其能够嵌入具有特定宽高度的矩形。这对于从视频生成缩略图非常有用。

我们建议使用此方法,而不是 getFrameAtTime(),因为后者会返回与源视频具有相同分辨率的位图,导致内存被浪费。对于 例如,4K 视频中的一帧将是 16MB 的位图, 需要使用缩略图

Shared memory API

Android 8.1(API 级别 27)引入了一个新的 SharedMemory API。借助此类,您可以创建、映射和管理匿名 SharedMemory 实例。您已设置内存保护 在 SharedMemory 对象进行读取和/或写入,并且由于 SharedMemory 对象是 Parcelable 时,您可以通过 AIDL 轻松将其传递给其他进程。

SharedMemory API 可与 NDK 中的 ASharedMemory 设施互操作。ASharedMemory授予访问权限 文件描述符,之后可将其映射为读取和写入。这是在多个应用之间或者一个应用的多个进程之间共享大量数据的理想方式。

WallpaperColors API

Android 8.1(API 级别 27)支持动态壁纸向系统界面提供颜色信息。为此,您可以创建一个 WallpaperColors 对象,或者使用三种手动选择的颜色。 您还可以检索该颜色信息。

如需创建 WallpaperColors,请执行以下操作: 对象时,请执行以下任一操作:

要从 则调用以下方法:

要通知系统动态壁纸的任何重大颜色变化,请执行以下操作: 打电话给notifyColorsChanged() 方法。此方法会触发 onComputeColors() 生命周期 您有机会提供新的WallpaperColors 对象。

如需为颜色变化添加监听器,您可以调用 addOnColorsChangedListener() 方法。您可以 还会调用 getWallpaperColors() 方法 来检索壁纸的主要颜色。

指纹更新

FingerprintManager 类包含 引入了以下错误代码:

  • FINGERPRINT_ERROR_LOCKOUT_PERMANENT - 用户尝试使用指纹读取器解锁设备的次数过多。
  • FINGERPRINT_ERROR_VENDOR - 发生了特定于供应商的指纹读取器错误。

加密更新

Android 8.1 在加密方面进行了多次更改。

  • 在 Conscrypt 中实现了新的算法。Conscrypt 与现有的 Bouncy Castle 实现相比, 实施。新算法包括:
    • AlgorithmParameters:GCM
    • KeyGenerator:AES
    • KeyGenerator:DESEDE
    • KeyGenerator:HMACMD5
    • KeyGenerator:HMACSHA1
    • KeyGenerator:HMACSHA224
    • KeyGenerator:HMACSHA256
    • KeyGenerator:HMACSHA384
    • KeyGenerator:HMACSHA512
    • SecretKeyFactory:DESEDE
    • Signature:NONEWITHECDSA
  • Cipher.getParameters().getParameterSpec(IvParameterSpec.class) 不再适用于使用 GCM 的算法。请改用 getParameterSpec(GCMParameterSpec.class)
  • 许多与传输层安全协议 (TLS) 相关的内部 Conscrypt 类都进行了重构。由于开发者有时会需要以反射方式访问这些类,因此保留了 shim 以支持以前的使用方式,但一些详细信息已发生变化。例如,套接字 之前的类型是 OpenSSLSocketImpl,但现在是类型 ConscryptFileDescriptorSocketConscryptEngineSocket,两者都扩展 OpenSSLSocketImpl
  • SSLSession 方法,用于抛出 在传递 null 引用时为 IllegalArgumentException,现在 抛出 NullPointerException
  • RSA KeyFactory 不再允许从大于编码密钥的字节数组生成密钥。调用 generatePrivate()generatePublic(),它提供 KeySpec,其中键结构未填充 将导致 InvalidKeySpecException
  • 过去,当套接字读取因套接字被关闭而中断时,Conscrypt 会从读取返回 -1。现在,读取会抛出 SocketException
  • 根 CA 证书集已更改,主要移除的是大型 删除过期证书的数量,同时删除 WoSign 和 StartCom。有关此决定的详细信息,请参阅 Google 安全博文:Final removal of trust in WoSign and StartCom Certificates(最终移除对 WoSign 和 StartCom 证书的信任)。