原文:Downloadable Fonts

译按:在 Android O 发布 Developer Preview 之后,我介绍了关于后台限制等一些行为和 API,发布在了 b 站。这一版本的 Android 看似没有什么改变,但实际上是对厂商做出了一系列规范,同时也给予了在合理范围内的可定制。虽然目前屏幕显示技术已不再对文字显示造成很大困扰,但电子设备上的文字处理现状并不乐观。今年的 Atypl 上,关于亚洲字体授权问题中提及,中国大陆移动设备上的字体业务收益颇丰。虽然开发者不一定需要阅读本地化开发文档,不过我的希望只是这一话题引起关注。如果看完了觉得有点意思,不妨通过文中链接去下一个示例应用在 Android Studio 调戏一番。


Android 8.0 (API 26) 和 Android 支持库 26 支持 API 从字体提供程序(Font Provider)中请求字体,而无需将字体绑定到 APK 中或让 APK 下载字体。这一功能通过支持库 26 在 Android API 14 及其更高的版本中运行。

可下载字体功能具有以下优点:

  • 减少 APK 的大小
  • 提高应用安装成功率
  • 多个应用通过一个提供程序可以共享同一种字体,从而提升了整个系统的健康。如此可节省用户的数据流量、手机内存以及存储空间。此模式下字体文件会在需要时通过网络获取。

可下载字体是如何工作的?

字体提供程序是一个可以获取字体并缓存到本地以便其他应用可以请求和共享字体的应用程序。

图 1. 可下载字体流程图

基础

您可以通过下列方式使用可下载字体功能:

  • 通过 Android Studio 和 Google Play 服务使用可下载字体。
  • 通过编程使用可下载字体。
  • 通过支持库使用可下载字体。

通过 Android Studio 和 Google Play 服务使用可下载字体

你可以使用 Android Studio 3.0 设置你的应用下载字体。为方便开始使用可下载字体功能,你可以使用 Google Play 服务中的字体提供程序。

注意 :使用 Google 字体提供程序的设备须具有 Google Play 服务 11 版或更高版本。

    1. Layout Editor 中,选择一个 TextView,然后在 Propertie 下,选择 fontFamily > More Fonts
      图 2. 使用 Layout edit

      出现 Resources 窗口。

    2. Source 下拉列表中,选择 Google Fonts
    3. Fonts 框中,选择一种字体。
    4. 选择 Create downloadable font,然后单击 OK注意 :选择 Add font to project 在应用中绑定字体。注意: 选择 Add font to project 在应用中绑定字体。
      图 3. 在 Resources 窗口中选择字体

Android Studio 自动生成在应用中正确显示字体所需相应的 XML 文件。

图 4. 预览字体文件

通过编程使用可下载字体

Android 8.0(API level 26)之前的版本中,支持库 26.0 对可下载字体提供完全支持。 更多关于支持库的信息,参阅通过支持库使用可下载字体的章节。

通过编程使用可下载字体功能,你需要同两个关键类进行交互:

  • android.graphics.fonts.FontRequest:此类允许你创建一个字体请求。
  • FontsContract:此类允许你创建一个基于字体请求的 Typeface 对象。

应用通过 FontsContract API 从字体提供程序检索字体。 每个提供程序对其支持的 Android 版本和查询语言都有自己的限制。 更多关于 Android 版本和查询格式的信息,请参阅你的提供程序的文档。

执行以下步骤下载字体:

1. 创建一个 android.graphics.fonts.FontRequest 类的实例以请求提供程序的字体。通过以下参数创建请求:

  • 字体提供程序权限
  • 用于验证提供程序的身份的字体提供程序包
  • 字体查询字符串。更多有关查询格式的信息,请参阅字体提供程序文档,如 Google Fonts
  • 用于验证提供程序身份的证书的散列字体提供程序权限的集合列表。

注意 :若从预装提供程序请求字体则无需要添加证书,但若通过支持库请求字体则必须始终提供证书。

FontRequest request = new FontRequest("com.example.fontprovider",
                   "com.example.fontprovider", "my font", certs);

注意 :你可以从字体提供程序接收参数值,Android Studio 自动为其 UI 中支持的提供程序填充这些值。

2. 创建一个 FontsContract.FontRequestCallback 类实例。

3. 覆盖 onTypefaceRetrieved() 方法以指示字体请求完成。提供获取的字体则作为参数。你可以根据需要使用此方法设置字体,比如设置 TextView 的字体。

4. 覆盖 onTypefaceRequestFailed() 方法以接收有关字体请求过程中的错误信息。更多有关错误代码的信息,可参阅 错误代码常量

5. 调用 FontsContract.requestFont() 方法以从字体提供程序中获取字体。此方法启动检查以确认字体是否存在于缓存中。若字体本地不可用,则调用字体提供程序,异步获取字体,并回调结果。根据以下参数:

  • 一个 Context 类实例
  • 一个 android.graphics.fonts.FontRequest 类实例
  • 一个接收字体请求结果的回调
  • 一个获取线程上字体的 Handler

注意 :确保此 Handler 非 UI 线程 Handler。

以下示例代码演示了可下载字体处理过程:

FontRequest request = new FontRequest("com.example.fontprovider.authority",
        "com.example.fontprovider", "my font", certs);
FontsContract.FontRequestCallback callback =
    new FontsContract.FontRequestCallback() {
        @Override
        public void onTypefaceRetrieved(Typeface typeface) {
            // Your code to use the font goes here
            ...
        }

        @Override
        public void onTypefaceRequestFailed(int reason) {
            // Your code to deal with the failure goes here
            ...
        }
};
FontsContract.requestFonts(context, request, callback , handler);

更多关于如何从字体提供程序下载字体的信息,可参阅可 下载字体示例应用

通过支持库使用可下载字体

支持库 26 对运行 Android API 14 或更高版本的设备提供可下载字体功能的支持。FontsContractCompatFontRequest 类包含于 android.support.v4.provider 包中,以实现对可下载字体功能支持的向后兼容。支持库的类包含方法类似于框架,下载字体的处理类似于下载字体章节中的。

android.support.v4.provider 包导入 FontsContractCompatFontRequest 类即可使用支持库下载字体。创建这些类的实例,而非 FontsContractandroid.graphics.fonts.FontRequest 框架类。

注意 :当你通过支持库请求字体时必须提供证书,包括预安装的字体提供程序。

添加支持库依赖关系

为使用 FontsContractCompatFontRequest 类,你需要在开发环境中修改应用项目的类路径依赖关系。

添加支持库到你的应用项目中:

  1. 打开你应用中的 build.gradle 文件。
  2. 添加支持库到 dependencies 部分。
dependencies {
    ...
    compile "com.android.support:support-compat:26.1.0"
}

使用可下载字体作为 XML 中的资源

Android 8.0 (API 26) 和支持库 26 为在声明作为 XML Layout 中资源的自定义字体提供了一种更快更便捷的方式。这意味着不需要将字体绑定为 asset,你可以为整个主题自定义字体,以提供多种字重和样式,如 Bold、Medium 或 Light。

    1. res/font 文件夹中创建一个新的 XML 文件
    2. 添加 <font-family> 根元素,并设置与以下示例 XML 文件所示的字体相关属性:
      <?xml version="1.0" encoding="utf-8"?>
      <font-family xmlns:android="http://schemas.android.com/apk/res/android"
              android:fontProviderAuthority="com.example.fontprovider.authority"
              android:fontProviderPackage="com.example.fontprovider"
              android:fontProviderQuery="example font"
              android:fontProviderCerts="@array/certs">
      </font-family>
    3. 参阅 layout XML 文件中的@font/font_file_name 文件,你也可以使用 getFont() 方法以编程获取文件,如 getFont(R.font.font_file_name)

在 manifest 中预声明字体

Layout inflation 和资源检索是同步任务。默认情况下,首次尝试检索字体会触发对字体提供程序的请求,从而造成第一个 Layout 延迟。为避免延迟,你可以在 manifest 中预声明需要检索的字体。系统从提供程序中检索字体后可立即使用。如果字体检索时间比预期要长,系统将中止提取过程,并使用默认字体。

执行以下步骤在 manifest 中预声明字体:

    1. res/values/arrays.xml 中创建一个资源数组,并声明要预读的可下载字体。
      res/values/arrays.xml
      <?xml version="1.0" encoding="utf-8"?>
      <resources>
          <array name="preloaded_fonts">
              <item>@font/font1</item>
              <item>@font/font2</item>
          </array>
      </resources>
    2. 使用 meta-data 标签在 manifest 中声明资源数组。
<meta-data android:name="preloaded_fonts" android:resource="@array/preloaded_fonts" />

添加证书

若未预装字体提供程序或你使用支持库,那么必须声明字体提供程序签名的证书,系统使用证书验证字体提供程序的身份。

注意 :如果你在 Android Studio 中使用字体选择器工具,Android Studio 可以自动填充 Google Play 服务提供程序的值。 更多有关使用 Android Studio 下载字体的内容,可参阅通过 Android Studio 和 Google Play 服务使用可下载字体的章节。

执行以下步骤添加证书:

    1. 创建具有证书详细信息的字符串数组。更多有关证书的信息,请参阅你的字体提供程序的具体文档。
      <?xml version="1.0" encoding="utf-8"?>
      <resources>
          <string-array name="certs">
             <item>MIIEqDCCA5CgAwIBAgIJA071MA0GCSqGSIb3DQEBBAUAMIGUMQsww...</item>
          </string-array>
      </resources>
    2. 设置 fontProviderCerts 属性到数组。
android:fontProviderCerts="@array/certs"

注意 :如果提供程序有不止一个证书集,你可定义一 个字符串数组的数组。


 

发表评论

电子邮件地址不会被公开。 必填项已用*标注