在這些眼花繚亂的新名詞后面,是怎樣的技術實現架構?體現了什么樣的設計思想?對于開發者來說,要怎么理解這些技術,并更好的利用新的平臺和機會接入自己的應用?
生來就為無處不在的 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 這些項目期望解決的并不是移植的問題,而是移植以后需要考慮的問題,包括
在各個設備上解決這些問題,是 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 包中,分別是:
由于設備和設備的通信可能耗時較長,用同步調用的方式很容易阻塞線程,因此,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 日趨豐富,諸如 Everynote、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 系統。對于開發者而言,這聽上去是很幸福的消息,“一次開發多處部署”的移動開發時代,就這樣到來了。