0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

现在Android平台也能顺利使用Emoji了

海阔天空的专栏 来源:谷歌开发者 作者:谷歌开发者 2022-06-02 15:08 次阅读

在移动互联网如此发达的今天,Emoji 已无处不在,并成为我们日常交流中不可或缺的一部分。据统计,Emoji 的使用率在过去 10 年内不断攀升,2021 年更是达到了历史新高,每天有超过五分之一的推文中包含了 Emoji,一些应用上的用户每天发送的 Emoji 数量更是达到了数十亿。然而用户在 Android 平台上使用 Emoji 时却存在着一些问题,本文将针对这些问题进行探讨,并向您介绍 Emoji 的工作原理以及 Android 平台近期关于 Emoji 的更新。

Emoji 在 Android 平台的现状

Emoji 在 Android 平台存在的问题

Unicode 每年都会对 Emoji 标准进行更新,用户越来越频繁地使用各种 Emoji,但却存在有约 96% 的 Android 用户无法正确查看新发布 Emoji 的问题,而 iOS 平台只有 16%,这一比例明显高出许多。

另外根据统计排名,前 100 位的 Emoji 占据了所有用户日常使用 Emoji 总量的 82%,但在约 20% 的情况下,当用户发送一个 Emoji 后,对方看到的却是豆腐块或一张损坏的图像,这种情况直接导致用户无法正确通过 Emoji 来传递自己的本意。如下图所示,用户发送了一张含泪的笑脸,但对方却只收到一个中间有 X 的方块 (我们称其为豆腐块)。

图片

△Emoji 在发送和接受方的不同显示效果

随着用户的增多,Unicode 也在不断增加新的 Emoji 来体现多元化和包容性,但是 Android 却并不能完全兼容这些新版的 Emoji,不同的 Android 版本对 Emoji 的支持程度也不同。比如以下的几个例子:

图片

△Emoji 无法在不同 Android 版本间正确表达多样性和包容性

  1. 在 Android 7.0 Nougat 和更早版本上无法正确通过 Emoji 表示肤色。用户发送了一个表示深肤色手臂的 Emoji,但对方收到的却是一个手臂和深色方块的分解版本。
  2. 在 Android 8.0 Oreo 和更早版本上无法正确显示代表中性的 Emoji。
  3. 在 Android 9 Pie 和更早版本上不支持显示多人多肤色的 Emoji。

Android 平台针对 Emoji 的解决方案

以上问题显然会导致非常糟糕的用户体验,并且不利于用户之间通过 Emoji 进行交流。我们的目标就是确保所有 Android 用户无论是使用哪种应用,都能够正常地使用每个 Emoji。为此,从 Android 12 开始,我们引入了可更新系统字体 (Updatable System Fonts),首先引入的便是 Emoji 字体,这也意味着开发者再也不需要在搭载 Android 12 以及 12 以上版本的设备中考虑 Emoji 适配的问题了,系统将默认支持新的 Emoji。

但是考虑到时光机还没有被发明出来,我们也没办法穿越到过去把可更新系统字体塞到旧版本的设备中去。如果一直等待时光机被发明出来而什么也不做的话,Android 12 版本之前的设备就会一直显示豆腐块,或者以其他错误的方式进行渲染。因此我们还是做了些改进,让您可以通过更新 Jetpack 库

EmojiCompat

解决这一问题:

https://developer.android.google.cn/guide/topics/ui/look-and-feel/emoji-compat

EmojiCompat 早在几年前就已经发布,2021 年我们对其做了很多改进,并将其整合至AppCompat 1.4版本中。为此我们开发了一个新库 androidx.emoji2,并添加了自动配置选项,它可自行配置以加载正确的字体。我们将这个库集成到了 AppCompat 1.4 中,也就是说,您仅需升级至 AppCompat 1.4 版本,便可在 API 19 及更高的版本上正常显示新加入的 Emoji,开箱即用,无需任何额外配置。

  • AppCompat 1.4 版本
    https://developer.android.google.cn/jetpack/androidx/releases/appcompat#1.4.1
  • androidx.emoji2
    https://developer.android.google.cn/jetpack/androidx/releases/emoji2


AppCompat 1.4 针对 Emoji 的优化

图片

△Emoji2 和 Emoji 对比

Emoji2 库是 AppCompat 库的一个新的依赖项,虽然它会代替现有的 androidx.emoji 库,但是 API 几乎相同。在此次更新中,我们使用 androidx.startup 添加了新的初始化程序 (EmojiCompatInitializer),添加了新的默认配置,并且全部支持了 nullability 注解。另外,相较于 androidx.emoji,我们还删除了一些在使用 AppCompat 时不再需要的 TextView 子类,这使得在 RA 之后节省了约 14KB 的大小。

  • Emoji2https://developer.android.google.cn/jetpack/androidx/releases/emoji2
  • androidx.emojihttps://developer.android.google.cn/jetpack/androidx/releases/emoji

图片

△Emoji2 加载 Emoji 的步骤

在这次更改中,一大新特性便是 EmojiCompatInitializer,它是一个使用了 androidx.startup 库的初始化程序,在应用启动时会自动配置 EmojiCompat。我们已对该初始化程序的性能进行了大量的调整,对于大多数应用来说使用默认配置已经完全足够,但如果您需要对应用启动做纳秒级别的优化,则可以考虑移除 startup 库和创建线程所带来的消耗。首先,确保先初始化 EmojiCompat,再执行 Activity.onCreate,这可以保证每个 TextView 都能显示新版 Emoji。然后,可以像 EmojiCompatInitializer 一样将 Emoji 字体加载延迟到首屏绘制之后,这样做是因为虽然加载过程是在后台线程中进行的,但它还是执行大量的网络和磁盘 I/O 操作,这些操作会同首屏加载一起抢夺资源。

这里再次强调,我们已对该初始化程序的性能进行了大量的调整和优化,除非必要,请使用 EmojiCompatInitializer 的默认实现。

pYYBAGKYYU6ARxuEAABPGqHk-_s700.png


另一个重要的功能是默认配置,在 androidx.emoji 中您需要从文档的示例代码中复制一些模版配置 (类似于以上代码) 到应用中,而 Emoji2 中我们添加了可以直接用于 EmojiCompatInitializer 的 DefaultEmojiCompatConfig,如下代码所示,只需一行简单配置即可,当然也支持手动配置的需求。

poYBAGKYYVOAFkV5AAAeVOGNZ3Q502.png

在 AppCompat 中,我们将 Emoji2 集成到了所有的视图中,这意味着所有视图都可以支持新版 Emoji,如果您的 Activity 继承了 AppCompatActivity,在 XML 中直接使用 TextView 或 EditView 即可。AppCompatActivity 安装了一个布局填充器 (LayoutInflater),它会用 AppCompatTextView 来替换 TextView 等视图,在代码中无论何时创建 TextView,都应该确保创建的是 AppCompatTextView,并且自定义视图应该继承相应的 AppCompat 子类。
所有集成了 Emoji2 的视图都有一个 EmojiCompatEnabled 属性,通过它可以控制是否开启 EmojiCompat,该属性还提供了 getter 和 setter 方法。EmojiCompatEnabled 属性有助于在知道文本绝不可能包含 Emoji 的情况下,来规避执行 Emoji 的处理逻辑,虽然即使不规避该逻辑所带来的成本也是极低的,但在某些情况下每一纳秒都至关重要,此属性便是为了支持这种情况。另外,该属性对于在后台线程上处理 Emoji 也很有帮助,AppCompat 对于 Emoji2 的集成会在 setText 之后的适当时间调用 EmojiCompat.process,您可以通过 EmojiCompatEnabled 属性禁用此方法调用,并对 Emoji 的处理移至后台线程。但通常这种优化没必要,除非是在 RecyclerView 中展示大量的文本导致卡顿,那么可以考虑采用这一优化方案。

测试新版 Emoji

由于集成了可下载字体,对于测试新版的 Emoji 并不是那么容易。要创建一个不会导致误报或漏报的通用自动化测试库很难,而大多数开发者在实际情况下会直接手动测试 EmojiCompat 的集成,因此最好的选择还是使用一个记录了用于测试的 Emoji 列表,同样此方式对于手动测试或对屏幕截图进行测试也都非常有用。


如果您希望了解更多信息,请查看文档:支持新式表情符号。我们在文档中为您提供了一些关于配置测试模拟器和设备所需要的一些操作建议:

https://developer.android.google.cn/guide/topics/ui/look-and-feel/emoji2

Emoji 渲染原理


图片

△一组码点

Emoji 属于一种图形字符,是字符串的一部分。它就像字母 "I"一样,只是绘制方式和从属的字体文件不同而已。但是对于计算机来说,它并不会特意关心什么是 Emoji 或字母 "I",一个字符串本质上就只是一组码点,其中的数字通过 Unicode 进行分配,代表着计算机上会出现的每一个字符。

现在 Unicode 并不仅仅只是一种格式了,它还代表了制定该标准的委员会,委员会会决定一些事情,比如数字 7 代表字母 "I" (实际上 7 并非真正代表字母 I 的码点,此处仅仅是举个例子)。那么当您试图在 Android 上渲染上述表示字符串的码点时会发生什么呢?


首先,Android 会根据码点和应用要求使用的字体样式为每个字符找出最佳字体。当前 Android 上非斜体且正常粗细 "V"的默认字体是 roboto-regular.ttf,Android 会对字符串进行遍历,检查每个字符并查找最佳字体。它会检查码点和样式,您可以对字符串进行样式的定制操作,比如对一些字符进行加粗等等。对于上述简单的字符串来说,它就只是会选择 roboto-regular.ttf 字体。

图片

△遍历码点查找正确的字符串

但是,当遇到 Emoji 字符时,您可能会觉得它会进行完全不同的渲染方式,毕竟它看起来不像任何其他的字母。但实际上,Emoji 就是个文本,由码点表示,同字母 "I"和 "I"一样没什么区别,绘制它的方式就存储到了字体中。Android 会首先尝试在字体中查找无斜体且正常粗细的 "融化脸",但这一次发现在 roboto-regular 中并没有想要的结果,便会去 NotoColorEmoji 中进行查找,这是 AOSP 上预装的 Emoji 字体,它包含了每个 Emoji 的图像,在 Android 平台上通过这种字体绘制 Emoji 和绘制字母 "I"的方式完全相同,都是查找字体文件后在屏幕上绘制出来。

图片

△通过 NotoColorEmoji 对 Emoji 字符进行绘制

在 Android 12 及以上版本中,平台可以确保 Emoji 会正常显示,因为可更新系统字体会将新版 Emoji 添加到字体文件中。但对于 Android 12 之前的版本,我们没有任何方法可以更新字体,这意味着 Android 不知道用什么字体来绘制 "融化脸",此时它会改为绘制一个称为豆腐块的备用字形。这里就是 Emoji2 开始大展身手的地方了。

图片

△Emoji2 对 Emoji 字符的绘制过程

在将字符串发送到 Android 系统之前,在字符串上会调用 EmojiCompat.process 方法,此调用将遍历并查找那些系统不知道如何绘制的 Emoji,并为每个 Emoji 添加一个 EmojiSpan,这是一个替换 Span,这意味着它将只替换该段字符串中对应的内容。系统会直接使用 roboto-regular.ttf 正常绘制,但当找到 EmojiSpan 时它会将绘制权转交给 Span。


在该 Span 中 Android 使用了两个方法,首先,它会获取字符尺寸并告诉 Android 要在文本布局中为此 Span 保留多少空间,然后,当需要绘制字符串时,它将调用 EmojiSpan 上的 draw 而非自行绘制。在 EmojiSpan 中,它知道 Compat 版的 Emoji 字体位置,并能直接从中绘制出 "融化脸"。再返回到渲染阶段,平台将调用 EmojiSpan.draw,整个区域将由 EmojiSpan 进行绘制,而非平台。实际上,从平台的角度来看 EmojiSpan 只是在字符串中间绘制了一张图片,并没有别的特殊操作。

总结

本文通过分析 Emoji 在 Android 平台存在的问题,针对不同版本的 Android 系统介绍了两种解决方案:

  • Android 12 及以上的版本使用可更新系统字体,无需开发者手动适配;
  • Android 12 以下的版本集成 AppCompat 1.4 也可自动适配新版 Emoji,无需额外操作。

此外,我们还介绍了 Emoji 的渲染原理,让您更进一步了解 Emoji 是如何呈现在屏幕上的。请记得升级 AppCompat 到 1.4 版本,为用户提供支持新版 Emoji 的最佳体验。

来源:谷歌开发者

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Andorid
    +关注

    关注

    0

    文章

    7

    浏览量

    6928
收藏 人收藏

    评论

    相关推荐

    微软Windows 11新增支持Emoji表情符号

    据Windows Developer官方账号发布的信息显示,用户可在Windows Terminal应用中使用命令提示符输入各类Emoji,以实现更具个性和趣味性的命令输入体验。
    的头像 发表于 04-11 11:26 89次阅读

    晶众合肥市交通规划数据模型及应用平台建设项目顺利通过初验

    2024年3月24日,在合肥市自然资源和规划局顺利召开了合肥市交通规划数据模型及应用平台建设初验专家评审会,晶众合肥市交通规划数据模型及应用平台建设项目顺利通过初验。
    的头像 发表于 03-25 15:25 183次阅读

    现在学鸿蒙有前途吗?找到工作?

    。发布会中表示,已有200家头部企业加入原生开发当中,并且一直有高薪抢人的局面。 做为Android开发人员,对于现在的互联网行业来说。鸿蒙就是近几年最大的风口,而不仅Android
    发表于 02-18 21:32

    那些杠鸿蒙的现在怎么样

    别杠,要杠就是你对。 一个纯血鸿蒙就已经打了那些杠精的嘴,以前是套壳Android,大家纷纷喷鸿蒙。现在鸿蒙已经全栈自研,并且已经展开各大企业生态合作。不管什么独立系统,都是一定要走一遍套壳
    发表于 02-16 22:03

    鸿蒙会取代Android吗?听风就是雨

    现在开发角度来看。Android市场的开发人才需求越来越少,不仅公司……
    的头像 发表于 01-31 16:48 202次阅读
    鸿蒙会取代<b class='flag-5'>Android</b>吗?听风就是雨

    Android、iOS、鸿蒙多平台框架ArkUI-X

    Android、iOS、鸿蒙多个平台上提供生动而流畅的用户界面体验。 一、配套关系 表1 版本软件和平台配套关系 目标平台 项目编译使用OS SDK版本 备注 OpenHarmony
    的头像 发表于 01-31 14:52 1043次阅读
    跨<b class='flag-5'>Android</b>、iOS、鸿蒙多<b class='flag-5'>平台</b>框架ArkUI-X

    基于Android平台的个性通讯录

    电子发烧友网站提供《基于Android平台的个性通讯录.doc》资料免费下载
    发表于 10-30 11:32 0次下载
    基于<b class='flag-5'>Android</b><b class='flag-5'>平台</b>的个性通讯录

    基于Android平台的手机通讯录管理系统

    电子发烧友网站提供《基于Android平台的手机通讯录管理系统.doc》资料免费下载
    发表于 10-30 10:13 0次下载
    基于<b class='flag-5'>Android</b><b class='flag-5'>平台</b>的手机通讯录管理系统

    基于Android平台的智能云导游系统研究

    电子发烧友网站提供《基于Android平台的智能云导游系统研究.pdf》资料免费下载
    发表于 10-24 09:20 0次下载
    基于<b class='flag-5'>Android</b><b class='flag-5'>平台</b>的智能云导游系统研究

    Xceed Toolkit for .NET MAUI -多平台UI控件

    MAUI的跨平台功能允许您开发在Windows、Android、Mac和iOS上顺利运行的应用程序,从而消除了对单独代码库的需求。Xceed致力于确保该工具包与所有支持maui的平台
    的头像 发表于 09-23 09:39 596次阅读

    iMX6常见 Android系统问题

    本文以飞凌嵌入式OKMX6Q/DL平台为基础讲解,其它iMX6 平台可参考使用,通过本文您可以了解iMX6 Android系统下一些问题的处理思路,希望可以协助客户加速产品的研发速度。 第一章
    发表于 08-29 10:32

    在 I/O 看未来 | Android 平台和质量更新一览

    作者 / 开发者关系工程师 Dan Galpin Google I/O 大会 是一场开发者的盛会,在此期间,我们向大家展示了与平台各方面相关的 精彩内容 ,其中大多数围绕应用质量。本文将为您带来
    的头像 发表于 07-04 17:45 263次阅读
    在 I/O 看未来 | <b class='flag-5'>Android</b> <b class='flag-5'>平台</b>和质量更新一览

    如何将memtool集成到i.MX8MM Android 12平台中?

    Memtool 是一个有用的调试工具,可以读/写一些 i.MX 寄存器。Linux 默认支持,Android 不支持。 本文介绍如何将 memtool 集成到 i.MX8MM Android 12 平台中,这在其他 i.MX
    发表于 05-16 06:56

    移植PN7150无法在Android平台读取身份证要怎么处理?

    移植PN7150无法在Android平台读取身份证(二代身份证明)。 我们测试读取一张TypeA卡是可以的。
    发表于 05-06 06:49

    如何在Arduino ESP8266和Android应用程序中正确地实现WebSockets?

    所以,现在迷上了新的 IOT 家庭自动化浪潮,并想为我的家庭构建一些应用程序(调光灯、热水器温度控制)。控制部分不是问题,我想我可以说,我在 Arduino 开发方面有很好的经验,比如在 C
    发表于 04-28 08:42