AI 年度盘点与2025发展趋势展望,50+案例解析亮相AICon 了解详情
写点什么

手机和平板之外——带你理解跨设备的 Android 技术体系

  • 2014-07-30
  • 本文字数:6463 字

    阅读完需:约 21 分钟

如果给 Android 撰写一个编年史,那每年的 Google I/O 都是一个新的 Android 年的开启,它预示着 Android 在后续一年新的方向和趋势。

2014 年的 Google I/O,新版本的 Android L 揭开面纱,它用 Material Design 重新定义了 Android 的交互方式。这种交互方式不仅适用于 Android 手机、平板等移动设备,也会延续到浏览器、手表、电视、汽车——这些 Android 即将出没的地方。Android Wear 定义了 Android 在可穿戴设备上的解决方案,Android Auto 将把 Android 带进福特、带进奥迪、带进你的座驾中,而 Android TV 则是 Android 占领电视、占领客厅的再一次尝试。

在这些眼花缭乱的新名词后面,是怎样的技术实现架构?体现了什么样的设计思想?对于开发者来说,要怎么理解这些技术,并更好的利用新的平台和机会接入自己的应用?

生来就为无处不在的 Android

Android Wear、Android Auto、Android TV……这些 Android 打头的不同设备解决方案目标是为了什么?这和市面上各式各样的 Android 电视、Android 手表、Android 盒子有什么不同?要说清楚这个,先要聊聊另一个话题:“可移植性”。

图 1:Android 架构图

从技术角度来看,Android 在整体架构设计上天生具有良好的可移植性,能够较为轻松的适配到不同的硬件设备上。如图 1 所示,Android 系统其实是构建在 Linux 内核之上的一个“运行时”(Android Runtime),由于 Linux 具有强大的可移植性,几乎可以嵌入到任何一个设备中运行,所以移植 Android 到新的硬件设备只需实现新的硬件抽象层(Hardware Abstraction Layer,HAL),按 Android 定义的标准为硬件上的 WiFi、相机等设备撰写驱动,而不需要修改上层的相关实现,难度大幅降低。

了解这一点就可以知道,将 Android 移植到不同的设备上并不是困难的事情,这也是非官方的 Android 电视、盒子可以很容易实现的原因。正是基于此,Android Wear 这些项目期望解决的并不是移植的问题,而是移植以后需要考虑的问题,包括:

  • 统一的交互模式。之前不同厂商定制的电视、手表等设备,缺少统一的交互模式和控件库的支持,不仅对于用户而言增加了学习成本,对于开发者而言,也较难基于不同的实现机制来构建应用,生态系统也就难于构建。Material Design 为不同的设备构建了统一的“设计语言”: Android Wear、Android TV 等项目在 Material Design 的设计语言基础上,针对不同设备的交互特征提供了界面库支持,使得应用适配不同的设备变得简单起来。尤其是,Android 还将 Google 的语音识别服务带到了这些不同的设备上,使得很多复杂的交互都统一到了“说话就好”的交互模式下。
  • 简单而统一的互联互通。不同设备有不同特征,在很多场景下都需要将各式设备“连接”起来,一起工作,才能发挥更大的价值。而现在如果你去买台第三方 Android 电视,要么是无法与其他 Android 设备通信,要么就是用各自不同的方案来解决,对用户来说学习成本高,对开发者来说则是不友好。而 Android Wear 这些解决方案,将互联互通实现到了 Google Play 服务中,实现到了 Android 系统中,使得连接变得简单而无缝,为开发者提供了更多的可能性。
  • 更好的解决核心需求。为什么出门要戴手表?为什么汽车需要车载系统?为什么客厅要摆电视?手表、电视这样的设备原本就有它需要解决的核心需求,引入 Android 到这些设备,本质上是为了更好的解决用户在这些场景的这些核心需求。Android Wear、Android TV 这些项目一方面是引入了大量 Google 服务来解决这些设备的核心需求,另一方面也为开发者提供了易用的、针对不同硬件场景的 API 来接入更多好的服务,一并更好满足这些需求。

在各个设备上解决这些问题,是 Android Wear、Android Auto、Android TV 这些解决方案共同的目标,以 Android Wear 为例,来看看 Android 是如何设计和解决这些问题的。

Android Wear

Android Wear 是基于 Android 的可穿戴设备的解决方案。早在今年的 3 月份,Google 就发布了 Android Wear 的预览版本,当时还并没有任何支持 Android Wear 的设备,开发者仅能够通过模拟器来感受 Android Wear 的面貌。

而到了 2014 年的 Google I/O,Android Wear 的版本已然打磨成型正式发布,搭载它的 LG、三星手表也同步发 (song) 售 (chu),其他可穿戴设备的预售信息也不断公布,这都使得对于开发者而言, Android Wear 不再是只能观望一下的东西,而是当下可以更清楚地了解、甚至是为它做点什么的方案。

连接

当你买来一台 Android Wear 的手表,你需要做的第一件事情是让它连上你的手机,否则它的作用至少折损了 80%。Google I/O 上对 Android Wear 的介绍中说,每个人每天都需要 125 次点亮手机,很多时候都只是看一眼手表、看一下通知、看一张 Google Now 的卡片,如果有了 Android Wear 这样的事情都可以通过手表更快速的完成,当然,这就需要先让你的手表连上你的手机。

图 2:a. Android Wear 预览版连接模式;b. Android Wear 正式版连接模式

从 Android Wear 的预览版至今,连接模块的实现架构经历了不小的调整。如图 2.a 所示,在预览版本中,连接的实现主要依赖安装在手机上的 Android Wear 应用和在手表上的 Android Wear 系统来实现。Android Wear 应用中包含了连接相关“服务端”的实现,而 Android Wear 设备作为“客户端”接入进来,如果手机上其他应用需要为 Android Wear 提供其他信息,可以通过绑定 Android Wear 应用声明多个的 Service,通过 Remote APIs 发送消息。

正式版的 Android Wear 实现(如图 2.b)引入了 Google Play 服务(Google Play Services)作为连接模块,Android Wear 应用和其他第三方应用的实现一样,通过 Google Play 服务的 SDK 构建连接发送数据。在可穿戴设备一端开发应用,也可以通过同样的模式来获取连接设备、读写数据。把连接封装到 Google Play 服务中有非常多的好处:一方面,Google Play 服务是 Android 的系统应用(在一些定制过的手机中并不是这样,而是需要自行安装或者用第三方实现替代),和系统一并部署,可以独立升级,让已经发布的 Android 手机都第一时间能够支持 Android Wear。另一方面,在 Android SDK 中也整合了 Google Play SDK 实现(需要通过 SDK 管理器额外下载),对于开发者而言学习成本很小,使用开发也非常的简单。

回到连接的底层实现,在预览版本中,移动设备和可穿戴设备主要是通过有线 / 无线的网络进行连接在移动设备端监听固定端口,可穿戴设备可以通过 USB 线(主要用在调试期间)或者 WiFi 网络建立直连的 TCP 通路,这个方式和豌豆荚 PC 版本的实现策略相仿,优势是数据传输速度快,缺点是连接不够方便稳定。

而在 Google Play 服务中,连接的链路主要是通过蓝牙这需要移动设备和可穿戴设备都开启蓝牙,然后进行配对、连接。由于可穿戴设备和移动设备的距离通常不会太远,因此使用蓝牙连接和传输都非常稳定,传输速度虽有所降低但还是可以流畅的发送指令、同步数据。其实连接链路的实现选择没有绝对的好坏评定,而是需要依照使用场景而定,比如在 Android Auto 项目中,车载设备和移动设备则主要是通过 USB 线进行连接,这是因为这些设备之间往往需要不间断传输大量多媒体文件数据,使用有线连接更为高速可靠。

通信

当设备连接完成后,就可以互相通信,交换数据了。在 Google Play 服务内部,连接和通信的协议都是通过 Protocol Buffers 定义的,但对上层屏蔽了这些细节,只暴露了三组接口,定义在 Google Play 服务的 gms.wearable 包中,分别是:

  • Node API用来查询有哪些设备已经连接上的 API,对于移动设备而言,就是看看有没有可穿戴设备连进来,反之亦然。
  • Message API用来发送消息的 API,所谓消息是由一个固定指令和一段小数据(通常不超过 100k)共同构成,用来发送控制信息,非常方便。
  • Data API用来发送数据的 API,通信协议定义接近于 Http,每个请求由 URI 和数据头、数据体构成,支持的数据类型和大小都很广泛,可以是简单的 key/value 类型也能支持文件传输,能够满足大多数的数据交互需求。

由于设备和设备的通信可能耗时较长,用同步调用的方式很容易阻塞线程,因此,Google Play 服务为其 API 定义了一致的异步编程模型。比如,如果使用 Message API 来发送一条消息,在发送方,编程模式形如:

复制代码
// 发送一条消息,同步获得一个 PendingResult,里面存放有后续会添加的发送结果
PendingResult<MessageApi.SendMessageResult> pending =
Wearable.MessageApi.sendMessage(
mGoogleApiClient, // 需要提前构建 API Client
node, // 用 Node API 来要获取到的目标设备
“wandoujia/hello”, // 需要发送的指令
null);
// 如果需要校验结果,可以阻塞的同步等待结果
MessageApi.SendMessageResult result = pending.await();
if (!result.getStatus().isSuccess()) {
……
}
……
// 也可以异步的等待回调(和上面片段二选一)
pending.setResultCallback(new ResultCallback<SendMessageResult>() {
@Override
public void onResult(final SendMessageResult result) {
if(result.getStatus().isSuccess()) {
……
}
}
});

而在消息接收方,则可以预先注册好回调,等待消息的到来:

复制代码
// 注册回调函数(仅示例,需要妥善注册和注销)
Wearable.MessageApi.addListener(mGoogleApiClient,
new MessageApi.MessageListener() {
@Override
public void onMessageReceived(MessageEvent messageEvent) {
// 收到回调,判定消息类型,进行处理
if (“wandoujia/hello”.equals(messageEvent.getPath()) {
……
}
}
});

高度抽象的通信层应用在了 Android Wear 、Android Auto 等解决方案中。比如在 Android Auto 中,车载设备的应用也是通过 Message API 和 Data API 于移动设备交互数据的。Google Play 服务统一的通信层设计、一致的异步开发模式,使得跨设备的通信实现非常地简单易学。

交互

完成一个可穿戴应用的开发,除了有底层的连接和通信支持,还需要完成交互界面的开发。Android Wear 的交互开发和 Android 移动设备大同小异,相同之处在于 Android Wear 的界面构成也是同样以 Activity 为单元,整体构成完全一致,不同之处是 Android Wear 为其定制了一套扩展的 UI 库,来满足手表等设备的交互需求。

这个 UI 库的设计,主要是为了让用户能够“看一眼”可穿戴设备的屏幕便能立刻了解相关信息,所以,它定义了一些适合可穿戴设备交互风格的 Activity、Fragment 和 View。比如 BoxInsetLayout,就是为了满足圆形风格界面在方形屏幕展示的排版需求;CardFragment 定义了一个支持可扩展且可垂直滚动的卡片界面,这是手表等设备上非常主流的信息呈现方式。总而言之,这个控件库中定义了可穿戴设备中最主要的信息展示和交互方式,因此在实际开发中,使用这些控件来构建交互界面是非常推荐的方式。

除此之外,语音在 Android Wear 中也是非常重要的交互方式,开发者除了可以在应用中通过 Android SDK 中 android.speech 进行语音识别快速获取内容,还可以通过配置 Activity 的 Intent Filter 来拦截系统定义的语音指令:

复制代码
<!-- 如果是一个叫车应用,可以拦截系统预设的打车指令 -->
<activity android:name="CallTaxiActivity">
<intent-filter>
<action android:name=
"com.google.android.gms.actions.RESERVE_TAXI_RESERVATION" />
</intent-filter>
</activity>

随着 Android Wear 预设的语音指令不断丰富,“语音启动” 可能会成为一个非常重要的入口,开发应用时合理的适配指令,可以让应用在用户想要的时候出现在他的面前。

拥抱 Android Wear

Android Wear 的目标,是让用户从不断的低头看手机中解脱出来,在可穿戴设备上更便捷的获取想要的信息。Android Wear 认为,各个应用呈现在通知栏上的通知信息,是移动设备中最需要立刻告知用户的内容。因此,当移动设备收到通知时,会立刻将通知传递到 Android Wear 可穿戴设备上,甚至还会发送至 Android Auto、Android TV 等其他设备上,就是为了让用户随时随地可以了解有什么信息需要他立刻处理,而不需要掏出手机、点亮屏幕、拉下通知栏。

所以对于 Android 移动应用的开发者来说,拥抱 Android Wear 其实非常简单,那就是优化一下自己应用的通知栏。一方面是要优化一下内容展示,把重要的信息直接展示在通知的标题和正文部分,使得查看时可以一目了然;另一方面,Android 在 v4 版本的支持包中(android support lib v4)提供了更具控制力的通知 API,开发者可以进一步丰富通知的样式、内容和操作,包括了支持大视图样式的通知、可多页展示的通知、支持语音操控的通知等等,甚至有的通知可以仅对 Android Wear 生效。比如,如果你开发的应用是一款聊天软件,原来应用通知栏显示的是收到两条新消息,为了更好的支持 Android Wear,你可以利用新的 API 把通知做成翻页模式的,每条通知都是一页,直接显示消息的内容,一目了然。

对于大多应用而言,有了如此强大的通知支持,可以完全满足用户在可穿戴设备上获取相关信息的需求。但如果需要在 Android Wear 的设备上占领入口提供更复杂的交互支持,抑或是专门针对 Android Wear 做一些功能,那都需要独立地为 Android Wear 来定制应用。而再进一步,如果这个应用还期望和移动设备有更多的数据和指令交互,那就需要使用 Google Play 服务提供的那些 API 完成相关的连接和通信。比如,可穿戴设备往往是不支持互联网访问的,如果期望定制的可穿戴应用是重度依赖网络的(比如 Google Now),那就需要在移动设备上有应用帮它完成网络访问,并通过通信 API 将数据传输过来。

虽然 Android Wear 才刚刚诞生不到半年时间,但随着搭载它的可穿戴设备的持续增多,提供的 API 日趋丰富,诸如 Evernote、Pinterest 等公司都已然行动起来,为 Android Wear 定制了应用,第一时间把服务从移动设备延展到了可穿戴设备上。如果你也看好可穿戴设备的未来,那是时候做点什么了。

无处不在的 Android

如果说 Android Wear 为风起云涌的可穿戴设备定义了一个标准方案,那么 Android Auto 则是对期望对纷繁的车载系统做一次统一。从产品和技术角度来看,Android Auto 都与 Android Wear 非常相近,比如从使用场景上看,Android Auto 也是期望用户在驾车的时间能够随时“看一眼”便了解当下最重要的信息;而从技术上看,Android Auto 也是需要随时随地保持与移动设备的连接,在通信层采取了和 Android Wear 完全一样的解决方案,在界面层也同样基于 Material Design 的理念定制了一套适合车载系统的交互控件。而两者最大的区别,在于引入的解决核心需求的手段不同,比如,Android Auto 认为用户在驾驶过程中,听音乐是非常核心的需求,因此它在多媒体的传输上做了大量的技术优化,甚至在传输链路上优先支持了 USB 的有线传输,在这个角度来看,说 Android Auto 是把汽车“穿戴”在了用户身上也不为过。

与之相比,Android TV 的技术实现会有所不同,它更像是 Android 平板之于 Android 手机。对于开发者而言,定制适合 Android TV 的应用,就像原来将手机上的应用移植到平板上一样,和开发普通应用无异,只需要使用 Android TV 提供的控件库,将应用做的更适合在电视上交互和获取内容即可。而对于 Android TV 这个解决方案而言,最期望解决的是可以在电视上无缝的融合各个数据源的内容,不论是通过电视信号、本地磁盘、还是网络流媒体过来的内容,都可以按照统一的方式呈现在电视上,在 Android L 中提供了新的 android.media.tv 包,帮助应用从更多的内容源来获取内容。

设想一下,如果 Android Wear、Android Auto、Android TV 都能如 Android 移动设备一样野蛮生长,那么也许有一天你触碰到的每一台电子设备都搭载了 Android 系统。对于开发者而言,这听上去是很幸福的消息,“一次开发多处部署”的移动开发时代,就这样到来了。

作者简介

范怀宇:豌豆荚应用平台技术负责人


感谢杨赛对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ )或者腾讯微博( @InfoQ )关注我们,并与我们的编辑和其他读者朋友交流。

2014-07-30 03:236643

评论

发布
暂无评论
发现更多内容

anyRTC RTSP转WebRTC方案

anyRTC开发者

音视频 WebRTC 直播 RTC 安卓

第六周作业

Vincent

极客时间 极客大学

追光逐影:焦距与镜头语言

北风

创作 生活 摄影 光影 摄影征文

数字资产会成为人类最大的资产

CECBC

数字资产 数字化时代 孙正义

111

不在调上

java安全编码指南之:字符串和编码

程序那些事

安全编码指南 java安全编码 java安全编码指南

对比 Redis 中 RDB 和 AOF 持久化

超超不会飞

再深入一点|binlog和relay-log到底长啥样?

艾小仙

Java MySQL 数据库 架构设计

【获奖名单公布】程序员摇身一变摄影师,属于技术人的摄影展示大赛

InfoQ写作社区官方

写作平台 征稿 热门活动

切片真的是引用类型嘛

Gopher指北

Go 语言

随想之UI+API

云杉

别闹,我用1个BTC居然买不了一个爱马仕包

猫Buboo

区块链+

第六周学习总结

Vincent

极客时间 极客大学

关于数据存储引擎结构,没有比这篇更详细的

华为云开发者联盟

数据库 nosql 存储

flutter之踩坑的日子(2)

霜蓝手环

小程序flutter, 跨平台 Flutter Android Apk

分库分表中间件的高可用实践

无毁的湖光

MySQL TCP 高可用 分库分表 高性能

anyRTC语音开黑demo正式上线

anyRTC开发者

音视频 WebRTC 直播 RTC

互联网只改变了商业的一部分,区块链将从根本上重构商业

CECBC

区块链 去中心化 互联网金融

Linux基金会唯一官方微服务培训课程免费学 | 快速构建稳定可靠的微服务应用

TARS基金会

开源 微服务 培训 Linux基金会 TARS

我是如何从0到1完成一个简单的中间件(1)

sinsy

Java 中间件

oeasy 教您玩转 linux 010215 随机谚语 fortune

o

血的教训!千万别在生产使用这些 redis 指令

楼下小黑哥

Java redis 生产事故

Golang领域模型-资源库

奔奔奔跑

微服务 领域驱动设计 DDD Go 语言

iPad Air把它大哥iPad Pro按在地上摩擦

徐说科技

查找数组中最大值的5种方法!(动图演示)

王磊

Java 面试

Spring 5 中文解析数据存储篇-Spring框架的事物支持模型的优势

青年IT男

Spring5 数据存储

“度拉拉”升职记:中国语音助手的成长史

脑极体

最新:央行副行长详解数字人民币,信息量巨大!

CECBC

人民币 数字人民币

这是一个奇怪的因果关系

陈磊@Criss

摄影

MySQL数据库技术与应用:数据查询

华为云开发者联盟

MySQL 数据库 存储

数字货币交易所源码开发,区块链交易系统搭建服务商

13530558032

手机和平板之外——带你理解跨设备的Android 技术体系_Android/iOS_范怀宇_InfoQ精选文章