HarmonyOS开发者限时福利来啦!最高10w+现金激励等你拿~ 了解详情
写点什么

手机和平板之外——带你理解跨设备的 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:236584

评论

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

docker如何在容器外执行容器内命令

A-刘晨阳

Docker Linux 运维 11月月更

Vue虚拟dom是如何被创建的

yyds2026

Vue

技术指南 | 如何集成Perforce版本控制系统Helix Core (P4V) 与软件生命周期管理工具Helix ALM

龙智—DevSecOps解决方案

版本控制 软件开发生命周期 版本管理 ALM

成为web前端工程师培训和自学选择

小谷哥

webpack热更新原理(面试大概率会问)

Geek_02d948

webpack

Nodejs+Redis实现简易消息队列

coder2028

node.js

js作用域、作用域链和它的一些优化

hellocoder2029

JavaScript

Go语言入门16—锁

良猿

Go golang 后端 11月月更

在线研讨会报名 | 如何通过自动化测试实现降本、增效与提质

龙智—DevSecOps解决方案

自动化测试 研讨会

AR Engine光照估计能力,让虚拟物体在现实世界更具真实感

HarmonyOS SDK

AR HMS Core

让数据流动起来,RocketMQ Connect 技术架构解析

阿里巴巴云原生

阿里云 RocketMQ 云原生

几个你必须知道的React错误实践

xiaofeng

React

用Vue.js开发企业管理后台,我做到了

博文视点Broadview

JavaScript刷LeetCode拿offer-js版字典

Geek_07a724

JavaScript LeetCode

linux(centos)中部署docker(步骤超全,含带一些发展史和一些概念)

A-刘晨阳

Docker Linux 运维 11月月更

干货|分析PostgreSql单表60w数据却占用55g空间

查拉图斯特拉说

数据库 postgresql db 11月月更

vue3实战-完全掌握ref、reactive

yyds2026

Vue

webpack配置优化,让你的构建速度飞起

Geek_02d948

webpack

javascript 高级编程 之 Array 用法总结

hellocoder2029

JavaScript

​GOPS演讲 | 如何构建现代运营与支持体系,实现团队的高效协同

龙智—DevSecOps解决方案

gops ITSM ITSM解决方案 GOPS全球运维大会

安装户外LED显示屏安装注意事项

Dylan

LED显示屏 户外LED显示屏 led显示屏厂家

HarmonyOS 3开启新一轮升级,3年前的nova 6也能更新!

Geek_2d6073

升级到React-Router-v6

xiaofeng

React

webpack模块化的原理

Geek_02d948

webpack

Nodejs相关ORM框架分析

coder2028

node.js

云栖盘点:2022 云网络产业干货分享

云布道师

云网络 云栖大会

开源代码安全 | 西门子为保护代码安全采取了什么措施?

龙智—DevSecOps解决方案

SCA SCA工具 开源代码安全

云栖盘点 | 一文 get 云原生峰会的最全发布

云布道师

云原生 云栖大会

vue中的几个高级概念

yyds2026

Vue

Nodejs:ESModule和commonjs,傻傻分不清

coder2028

node.js

javascript尾递归优化

hellocoder2029

JavaScript

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