Android 开发,你赶上 Emoji 头疼吗?

188

在 Android 中,若是须要使用的到 Emoji 表情,你会发如今某些设备上,有一些 Emoji 表情会被以豆腐块 “☐” 的形式显示,这是由于当前设备并不支持这个 Emoji 表情。html

而在 Android Support 中,新增长了一个 EmojiCompat 来专门解决这个问题,EmojiCompat 对 Android 4.4(Api Level 19)以及以后的系统,进行 Emoji 的扩展支持!android

接下来咱们就来了解使用 EmojiCompat 的全部细节!算法

1、什么是 Emoji?

既然要用到 Emoji ,咱们先来了解一下什么是 Emoji。c#

Emoji 是能够被插入文字中的图形符号。它是一个日本语,e 表示"绘",moji 表示 "文字" ,连在一块儿就是 “绘文字”。设计模式

Emoji 最先是上个世纪 90 年代的时候,又日本电信商率先支持,就是为了在短信中,插入表情,来加强短信的体验。2007 年,Apple 在 iPhone 中支持了 Emoji,才让它在全球范围内流行起来。app

iphone-emoji

早期的时候,Emoji 的实现是将一些特殊的符号组合替换成图片表情,例如 :) 替换成 ? ,这样的解决方案会致使很难将 Emoji 的表情标准化,并且表达的范围也有限。iphone

2010年开始,Unicode 开始为 Emoji 分配码点,也就是说,在那以后的 Emoji 符号,就是一个字体,它会被渲染为图片显示。ide

Emoji 因为其表达情绪的特色,被广受欢迎。Emoji 的国际标准在 2015 年出台,如今已是 5.0 版本了,而在 2018 年,将发布 Emoji 6.0(以后会重命名为 Emoji 11,其实就是 Emoji 5.0 的升级版) 版本的标准。学习

截止到如今,Emoji 5.0 中,被列入 Unicode 的已经有 2623 个了。字体

具体细节能够在这个网站中查询到:

http://www.unicode.org/emoji/...

到这里你们应该清楚,Emoji 在标准化后,其实就是一个字体,它被 Unicode 分配了固定的码点,通常咱们就用标准的 Unicode 来标识一个惟一的 Emoji。

虽然 Emoji 已经被标准化了,可是不一样平台由于使用的字体不一样,致使一样的 Unicode 表明的 Emoji,被渲染显示出不一样的效果。

emoji-transfrom

例如这里举的例子,标准的 Emoji U+1F601,在 Apple 和 Android 中,虽然一样表示一个笑脸,可是渲染的效果是不同的,这一点咱们须要了解到。

2、Emoji 在 Android 中的现状

2.1 如何使用 Emoji?

一个标准的 Emoji ,实际上是有多种表示方法的,举个例子,先看看前面说的笑脸 U+1F601

xiaolian-emoji

Code、UTF-八、Surrogates 这些形式,均可以表示这个笑脸的 Emoji。一般这个 Emoji 表情是来自用户输入的数据或者服务端传递过来的数据,虽然这些形式均可以表示这个 Emoji,可是不一样的格式就须要不一样的形式来解析。

正常来讲,咱们推荐使用 Surrogates 传递 Emoji,例如:\uD83D\uDE01,它自己就是一个 Unicode 的编码,是通用的,能够在 TextView 中直接使用就能够显示。

xiaolian-unicode

但是,假如咱们获得的并非 Surrogates ,而是 Code ,例如 1F601,这样咱们就须要进行额外的处理了。其实也很简单,通过几步转换就能够作到。

String(Character.toChars(Integer.parseInt("1F601", 16)))

例子中使用的是 Kotlin 代码,不过应该不影响阅读。

将生成的 String 对象,传递给 TextView,若是是当前设备支持的 Emoji,就能够正常显示了。

2.2 Emoji 显示不出来状况

上一小节介绍的方式,其实咱们是没有作任何特殊处理的,彻底是以来设备本身的字体库来进行 Emoji 渲染的。这就会致使有一些 Emoji 在某些设备上显示不出来的状况。

使用这种方案,我用我手边的设备运行以后,来看看显示的效果。

emoji-normal-test

很清晰的看到,这里有一些 Emoji 没法显示,会被显示成一个豆腐块 “☐” ,而这并非咱们想要的。

接下来咱们来看看使用 EmojiCompat 如何来处理它。

3、使用 EmojiCompat

3.1 什么是 EmojiCompat

根据官方文档描述,EmojiCompat 支持库主要是为了让 Android 设备,达到最新的 Emoji 符号的显示效果,它能够防止应用中,出现以豆腐块 “☐” 的形式来显示 Emoji,虽然它仅仅只是由于你当前的设备没有这个字体而已。经过 EmojiCompat ,你的设备无需等待 Android 系统更新,就能够得到最新的 Emoji 表情显示效果。

emoji-comparison

3.2 如何使用 EmojiCompat

EmojiCompat 支持库,最低支持到 Android 4.4(Api Level 19) 的系统设备。

EmojiCompat 提供两种字体的支持方式,它们分别是:

  1. 可下载的字体配置。
  2. 本地捆绑的字体配置。

这两种使用方式,除了引用的库不一样以外,最根本的缘由在于,可下载的字体的方式,会在首次启动的时候检查本地是否有该字体,没有的话会从网上下载最新的 Emoji 字体;而本地捆绑的方式,会在 App 打包的过程当中,植入一个最新的 Emoji 字体文件,而后遇到不能支持的 Emoji,就会从这个字体文件中,加载资源而且渲染。

目前官方使用的是 NotoColorEmojiCompat.ttf 字体文件,后面会详细讲解到。

我想你应该发现了,本地捆绑的方式会嵌入一个字体文件,无形中增大了 Apk 安装包的体积,可是可下载字体的方式,又彻底依赖 Google 服务,因此在国内基本上是处于残废状态,在这个大环境下,咱们这里只能选择本地捆绑的方式来使用 EmojiCompat。

不管使用哪一种方式配置字体,对于 EmojiCompat 而言,实际上是不关心的,它只须要判断当前设备是否支持这个 Emoji,支持就使用系统内置的,不支持的话,就使用 EmojiSpans 来替换 CharSequence,来达到替换渲染的效果。

EmojiCompat 的运行原理以下图所示。

emoji-support

3.3 本地捆绑的字体配置方式

既然可下载的 Emoji 字体,须要配合 Google 服务,那这里就再也不过多介绍了。

本文主要讲解如何使用本地捆绑的方式,使用 EmojiCompat。

第一步,须要添加 Gradle 依赖。

dependencies {
    ...
    compile "com.android.support:support-emoji-bundled:27.0.2"
}

第二步,初始化 EmojiCompat。

初始化 EmojiCompat ,须要两个步骤。

  1. 首先须要生成一个 BundledEmojiCompatConfig 对象,它的构造方法接收一个 Context。
  2. 再调用 EmojiCompat.init() 方法,将前面生成的 config 传递给它进行初始化。

emoji-init

这个过程越早越好,由于初始化是耗时的,它会去加载打包的时候,嵌入的 Emoji 字体文件,因此大概须要消耗 150ms 的时间,而且占用大概 200kb 的内存。

第三步,使用 EmojiCompat。

初始化完成以后,就剩下如何使用它了。

EmojiCompat 的处理逻辑,前面已经使用图片描述清楚了。它会加载一个 Emoji 字体,而后判断当前设备是否支持须要显示的 Emoji,若是不支持,则使用 EmojiSpans 替换它,最终将处理过的 CharSequence 设置到 TextView 上。

而这个过程,EmojiCompat 提供了很是简单的方法,process()

compat-process

从它的签名能够看出,它接受一个 CharSequence 并处理它,而后返回一个 CharSequence。

举个例子:这里转换一个笑脸的表情。

EmojiCompat.get().process("笑脸: \uD83D\uDE01")

process() 须要接受一个 Unicode 的字符,因此若是获得的数据是前面提到的 Emoji Code 的话,就须要一步单独的转换。process() 内部已经帮咱们完成了转换,这些细节都无需咱们关心,咱们只须要将它返回的 CharSequence 设置给 TextView 就能够了。

3.4 Emoji AppCompat Widgets

在实际项目中,若是每次都须要经过 EmojiCompat.get().process() 对字符串进行处理,其实也挺麻烦的。为此 Google 还为开发者提供了对应控件支持。

若是须要使用它,就须要引入新的依赖库。

dependencies {
      compile "com.android.support:support-emoji-appcompat:27.0.2"
}

引入以后,就能够直接在 XML 中使用 EmojiAppCompat 提供的控件。

emoji-widget

使用 support-emoji-appcompat 只是节省了咱们 process() 的步骤,可是依然须要 init()

3.5 自定义控件支持 Emoji

你能够一直使用 progress() 或者使用 EmojiAppCompatXxx 控件,可是若是你想要自定义一个控件来显示 Emoji,就须要使用 EmojiCompat 提供的另外两个帮助类。

  • EmojiTextViewHelper
  • EmojiEditViewHelper

这两个使用起来很是简单,一个用于处理纯展现的控件,一个用于处理有输入的状态的控件,很是的简洁明了。

哪怕不记得了,看看 EmojiAppCompatTextView 和 EmojiAppCompatEditView 中的实现方式就能够了。

AppCompatTextView

这里拿 EmojiAppCompatTextView 举例子,只须要在几个关键的位置上,使用 EmojiTextViewHelper 的对应方法便可。

3.6 EmojiCompat面临的问题

总体来讲 EmojiCompat 仍是很好用的,不管使用哪一种方式加载它,实际上咱们都不须要作过多的干预。

这里参考官方文档,列举最多见的几个问题。

一、下载字体的下载策略是怎么样的?

Emoji 字体在第一次使用的时候,会检测是否存在于当前设备,若是不存在则在子线程中进行下载。

二、初始化须要多长时间?

当本地已经有字体以后,初始化 EmojiCompat 大约须要 150 毫秒。

三、EmojiCompat 支持库,会使用多少内存?

目前,Emoji 字体被彻底加载以后,会使用大约 200kb 的内存。

四、在 Android 4.4 如下的设备上,使用 EmojiAppCompatXxx 控件会发生什么状况?

EmojiCompat 内部已经作了兼容处理,在低版本上就和使用普通的 AppCompatXxx 控件同样。

五、本地捆绑的 Emoji 字体文件,大约有多大?

本地捆绑的 Emoji 字体文件 NotoColorEmojiCompat.ttf,会在打包的时候嵌入到 assets 目录下,如今实际状况来看大小有 7.4MB,这会直接形成 Apk 的增大。

更多的细节,仍是建议你们阅读官方文档。

https://developer.android.goo...

4、EmojiCompat 的缺陷?

在实际使用 EmojiCompat 的过程当中,还遇到了一个不能算缺陷的缺陷。

咱们来回忆一下以前提到过的,EmojiCompat 的处理机制。

emoji-support

它只有在当前设备遇到不被支持的 Emoji 的时候,才会从 Support Font 中加载字体,若是有,它会使用 System Font 。

这也不能怪 EmojiCompat 的设计者,它的出发点,是为了解决 Emoji 在某些设备中,显示豆腐块 “☐” 的问题,而不关心它究竟是不是显示最新的 Emoji,是在解决有无的问题。

这就很尴尬了,其实有时候 Android 设备内置支持的字体,显示的效果并很差,咱们先来看看使用 EmojiCompat 先后的对比效果。

emoji-duibi

左边是没有使用 EmojiCompat 的效果,而右边是使用过的效果。

很清晰的能够看到 EmojiCompat 帮我补齐了我当前设备部支持的那些 Emoji 表情,可是并无将 Android 的果冻表情替换为标准的 Emoji 表情。

那么,若是咱们想要让它显示最新的 Emoji ,咱们须要这么办呢?

前面提到,自从 Emoji 开始被标准化以后,其实就是一个字体,而且 EmojiCompat 也是帮咱们捆绑嵌入了一个字体包在 assets 目录下,那咱们只须要让咱们显示的 TextView 加载这个 Emoji 字体,就能够解决这个问题。

有了思路,咱们就来试试这个解决方案是否可行。

emojiUtils

到此,咱们就能够经过调用 loadEmoji() 方法,让 TextView 显示 Emoji ,来看看对比的效果。

emoji-duibi3

从左到右,分别是:默认 Emoji、EmojiCompat、Emoji Font 的显示效果。

密密麻麻的表情有点多,密集恐惧症请放过我,?!

固然,这里只是提供一个解决方案,采用此方案的状况下,基本上全部 4.4 以上的机型,均可以显示最新的 Emoji,若是对 Emoji 的显示效果有要求,这也不失为一个解决方案。

5、总结

到此,就是我所了解的 Android 下的 Emoji。

看完本文你有什么收获?或者你有什么更好的关于 Emoji 的建议,欢迎在留言讨论!

今天在 承香墨影公众号的后台,回复『 成长』。我会送你一些我整理的学习资料,包含:Android反编译、算法、设计模式、虚拟机、Linux、Kotlin、Python、爬虫、Web项目源码。

推荐阅读:

据说喜欢留言的人,运气都不会太差

点击『阅读原文』查看更多精彩内容

https://mp.weixin.qq.com/mp/p...

相关文章
相关标签/搜索