CIO
|
PCDIY!
|
旗標圖書
|
旗景數位影像
|
讀者服務
首 頁
即時新聞
業界動態
最新活動
企業採購
精選文章
線上教學
品牌活動
程式碼下載
雲端運算智庫
最近新增的
精選文章
AP內建AI引擎 Mist Cloud平台分析能力強 Juniper Mist AI領先全球 改善WiFi穩定、效能首選
解決IT供應鏈攻擊
內部威脅的七個警訊
遠百以專案辦公室推動數位體驗
多廠牌與多重電信業者網路架構的挑戰與機會
德明科大啟用電貿暨AI實習基地 ViewSonic ViewBoard 智慧互動電子白板 扮要角
淺談計算誤差
秀傳醫療體系統 以Lenovo HyperConverged HX 超融合架構扎穩智慧醫療發展基礎
模組化設計 偵測率達99.99% 全面防杜惡意郵件入侵 首選Cellopoint Email UTM
滿足網路管理與檔案安全傳輸需求,Ipswitch的MOVEit及WhatsUp Gold一次完整提供
來自學界的資料分析利器 - Weka 與 R
北醫建置肺癌資料庫,透過深度標註訓練AI,協助醫師早期發現癌症
北榮AI門診上路!人工智慧判讀腦瘤,有效縮短醫師確診時間
台灣智慧機器人玩具聯盟攜手英閱音躍研創 推廣T. Robot程式教育,協助國中小學扎根培養運算思維
一場與時間賽跑的戰役 ,人工智慧加速心血管疾病診斷
最多人點閱的
精選文章
免費IT建置--Linux系統操作與管理
初探Hadoop開放原始碼平台環境
免費IT建置--網頁伺服器的完美組合LAMP(下)
免費IT建置--檔案共享與檔案伺服器
Linux下的防火牆(基礎篇)
Linux下的防火牆(進階篇)
N.Y.BAGELS CAFE善用SAP Business One
手機程式設計入門與應用 Android、iPhone、Windows Mobile─ 影片播放器範例
手機程式設計入門與應用 Android、iPhone、Windows Mobile─ 線上查詢匯率
手機程式設計入門與應用 Android、iPhone、Windows Mobile─ 擲骰子遊戲
手機程式設計入門與應用 Android、iPhone、Windows Mobile─ 音樂播放器範例
手機程式設計入門與應用 Android、iPhone、Windows Mobile─ 來電黑名單
免費IT建置--網頁伺服器的完美組合LAMP(上)
手機程式設計入門與應用 Android、iPhone、Windows Mobile─ 繪圖板範例
手機程式設計入門與應用 Android、iPhone、Windows Mobile─ Matrix應用範例
精選文章 - 開發技術
分享到Plurk
分享到FaceBook
Android車載系統(2)
Android車載服務平台的通訊機制
文/圖 徐士欽.責任編輯/洪羿漣
Android為目前當紅的手機開發平台,在Google的用心下,將其打造為一個易用、穩定且順暢的作業系統,而其免費且開放原始碼的特性,更是讓所有開發商欣喜不已,紛紛採用為新手機的作業系統。比起以往各家作業系統的遙不可及,現在一般的手機玩家只要有一點JAVA程式基礎,便可輕易的在自己的Android手機上開發屬於自己的應用程式,打造專屬自己的手機。
欲開發程式時,非常重要的一個技術便是程序間的溝通(Inter Process Communication, IPC),IPC的技術隨著不同的平台上會有著不同的做法,一般常見通用的有Socket、資料庫、檔案等手段。
而Android上面除了這些通用的手法之外,還自行設計了幾種不同的通訊方式,可因應不同情況使用不同的做法。在這篇文章中,我們將針對Android自己獨有的IPC機制做一個介紹,使讀者能夠有個全面的了解。
元件與程序
開始介紹IPC之前,必須得要對應用程式在系統中的地位有個基本了解。當我們在Android系統上面設計應用程式時,最常接觸的便是其介面裡的基本元件,如Activity、Service、Provider等,其中Activity為我們最常用到的基礎元件,它實際上便是代表著我們所看到的使用者介面,元件的內容並非此篇文章的主題,在這邊我們就不深入介紹,但是在本文中只要了解一件事情即可,這些元件是構成應用程式的主體們。
一般情況裡,我們撰寫的應用程式(也就是在手機上點兩下可以執行的東西),在系統中是由一個Process(程序)來執行,而每個Process裡面一定會附帶一個Thread(線程)。有些時候,應用程式裡的主Process會自己產生更多的Process,也有可能會自己產生更多的Thread;更多的狀況下是在自己開發的應用程式中要對其他的Process做一些命令的下達或者是交換資料。
由於Process存在不同的記憶體區塊內而且是由系統進行控管,所以我們無法直接從程式裡面寫個「x=10;」這樣的命令,就將資料交遞給其他的Process,而是得要透過作業系統來幫我們達到這樣的目的。
此時就會用到系統設計的IPC機制,當然也可以在兩個不同的Process約定好,直接使用存取檔案或者Socket的方式來達到資料交換的效果,不過本文中就不去探討這樣的做法。
在圖1中就說明了一種常見的情形,有2個應用程式,編號1中包含了2個Process,而這2個Process則分別包含了一個Thread,其中一個Thread中有一個Activity的元件,另一個則是Service的元件。同樣的,編號2也是類似的架構。
圖1 IPC示意圖。
在這樣的架構下,當不同的Process之間要交換資料時,便要使用IPC的溝通機制。像編號1這樣的架構,是常常被使用的,最常見的例子便是MP3播放器。
由於MP3音樂是要被持續播放的,所以我們會使用Service這樣的元件,來達到背景執行的效果,但是使用者仍需要另一個操作介面來對音樂做暫停、快轉等控制動作,所以又得要有另一個Activity的元件來實現操作介面,於是便會形成了編號1這樣的架構,而其中的通訊也就成了無可避免的課題。
Intent與IPC
Android的IPC機制,廣義的來說包含好幾種不同的方式,總共包含以下幾種做法:
1.使用Intent元件。
2.透過Binder綁定機制進行遠端呼叫。
3.使用Android Interface Definition Language(AIDL)介面機制。
Intent,中文譯為目的或意圖,這是一個很方便且聰明的機制。而不同的方法有著不同的優缺點以及其限制,使用時選擇最適合自己的機制可以達到最佳的效率。但無論是哪種語言,無論在哪種平台,我們常常會考慮的一個通訊架構便是「事件觸發」。
所謂事件觸發,指的是我們發出一個消息,告訴處理中心說:「現在我有個事件,請你幫我處理」,然後處理中心便會依據我們發出的事件類型,尋找適合的機制來進行處理。拿現實生活來說,便是類似服務台的機制。
那這個部分跟我們的IPC有甚麼關係呢?我們換個角度來想想,某人(Process A)發出了一個「事件(Intent)」,將其給予了服務中心(Android作業系統),服務中心找出處理這事件的方法(另一個Process B),接著將我們的問題交給專人(Process B)處理,最後完成事務。我們現在介紹的第一個Intent元件,便是使用這樣的設計架構實現出來的機制。
下面我們使用一個簡單的喚起其他Service做為範例,來了解Intent機制使用步驟:
1.首先在AndroidManifest.xml檔案中,對要負責接收此Intent的Service部分加上說明。圖2中我們可以看到,針對IIIService這個Service的定義加上對於Intent的過濾條件,也就是說,之後只要符合Intent的定義,就會跟此Service進行關聯的動作。
圖2 只要符合Intent的定義,就會跟此Service進行關聯。
2.生成一個Intent並設定其行為與資料,如圖3範例中,我們僅設定行為(action)的部分,可以看到圖3與圖2的設定是互相對照。
圖3 生成一個Intent並設定其行為與資料。
3.丟出Intent,我們呼叫startService直接將Intent送出去,在這邊我們直接寫成一行。到這邊我們的工作便完成了,可以在程式裡看到另一個Service被呼叫起來。
Intent最常被使用的時機,是用在喚起其他的Activity,並將資料攜帶傳遞過去,例如我們希望在應用程式中,按下一個按鈕之後能喚起瀏覽器,自動連到某一個網頁;或者是按下按鈕後,跳出一個新的視窗程式。
在上述的狀況中,通常都會使用Intent做為媒介,因為這是最直接也最容易處理的方式。在Android的系統中,Intent有著各式各樣的使用方法,你可以使用intent.setClass()來設定Intent發送給特定的class,也可以使用startActivity()來喚起其他元件,並傳送資料。在本文中就不詳加介紹各式各樣的Intent用法,但是它是一個最常被使用的IPC機制,如果你的應用程式用於簡單的訊息傳遞、啟動或者切換畫面,使用Intent便可以解決大部分的問題。
Binder與IPC
Binder機制是Android應用框架裡面一個很重要的機制,它最主要的工作是將各個不同的Service做一個Bind(連結)的動作,也就像是一個管理著所有Service的中心。
拿一個現實中的例子來說,我們將Service當作是一輛一輛的車,而Binder機制中的Binder Driver這個東西,就像是停車場。若想找到自己的車,只要到停車場去找,就可以找到了。透過這樣的機制,我們得以取得其他Service的介面,藉此與他進行溝通的動作。
我們先來了解一下Binder與Service的關係。Service主要可以分為2種,一種是我們在元件裡面定義的Service,而另一種是在底層建立起來的系統Service。系統Service簡單來說,就是已經寫好的一些底層操控API。
若想要播放音樂,不可能從最底層的Audio Driver開始實現,我們通常的作法是直接使用SDK裡面提供的API,但是終究還是要有人來把底層的部分做好對吧,所以雖然我們使用的是SDK的API,但深入去看實際運作的部份,還是使用底層的系統Service,圖4中就說明了此種架構。
圖4 Service與Binder關係圖。
圖4中我們可以看到自行創建的Service,會使用系統提供的MediaPlayer相關API,而API則是透過了JNI(Java Native Interface)的介面,來直接呼叫底層的C++相關函式。其函式則是透過了MediaPlayerService所提供的介面,來實際對硬體進行操作的動作。
我們也看到Binder機制裡面的Binder Driver,在此扮演了記錄各種不同的系統Service角色,記錄著不同Service的連接接口。在這邊要補充說明的是,Binder並不只是記載系統Service的接口,而是記錄著「所有」的Service的接口,我們自定義的OurService也會被記錄在其中。
採用方法的考慮因素
有寫過Service的讀者應該會發現,當建立自己的元件時,需要複寫一個名為onBind的Method,這便是跟Binder相關的Method。圖5為一個簡單的Service範例,其中便有前文中所提及的onBind的Method。
圖5 簡單的Service範例。
這邊必須先介紹一下Service Management,如果我們將Binder Driver比擬為停車場,那Service Management就像是停車場的管理員了,管理員管理著整個停車場,當我們找車找不到時便可以連絡管理員,請求協助。
所以在Binder機制裡,實際上控管Service的是Service Management,我們要找某一個Service也都是向他請求,而他自己本身,也是一個Service,當系統開機時,便會將Service Management載入到Binder Driver裡面,成為第一個Service,之後其他的Service加入時再向其登錄資料。
當我們在程式中想要透過Binder來與其他Service通信時,首先得要向Service Management取得目的Service的Binder物件,接著使用Transact() Method,便可以透過Binder Driver將消息傳遞到目標Service的OnTransact() Method,然後執行相關動作,達到IPC的效果。
但是在Binder裡面能夠用於傳輸的只有OnTransact()與Transact()這一對的函式,在使用上會有較多的限制,所以若應用程式中要用到的功能很少,也沒有要存取對方物件的Method,使用此機制是不錯的選擇。
然而上述的方式與Intent差異在哪呢?Intent是上層的資料交換,當你使用到Binder的時候,便是直接透過JNI與底層的Binder作互動;相比之下,使用Intent只要輕鬆的設定一些東西即可,所以一般狀況下使用Intent是比較輕鬆的選擇。但是若溝通的目標Service是想要直接與底層的Service溝通,那使用Binder會是比較好的做法。
AIDL與IPC
在前面我們介紹了Binder的做法,這樣的做法不免讓人覺得限制頗多,最主要是因為只有Transact()這個Method可以使用,當你想使用對方的其他Method時,便顯得較不方便。當然你可以在連結成功後,再使用本地的Method,但是繞這麼大一圈,若有很多Method要使用,便會顯得繁複。
為了解決這樣的問題,於是有了AIDL的機制。AIDL,全名為Android Interface Definition Language,如其字面翻譯,它是一個讓你可以自行定義你要開放的介面的工具。原理很簡單,它背後也是使用Binder的機制完成,我們所要做的,就是使用它的AIDL工具,來產生相關的檔案,然後實現你希望開放的介面。
再來就是將你打算開放的介面開放出來給其他程式使用,實際上的操作就不在這邊介紹。這種做法適合用在程式中希望能有不同的介面可以直接存取時,不過在撰寫上需要多一些步驟。
以車載裝置服務平台為例
依照不同情形選擇適當的機制會達到最好的效益,以資策會開發中的車載裝置服務平台來說,我們開發基於OSGi(Open Service Gateway Initiative)各式核心處理程序,以達到動態加載服務及卸載的動作。然後結合TR-069的通訊系統進行遠端管控的動作。
由於遠端控管到了本地端時,使用了另一個程式來對OSGi作控制的動作,其中的IPC通訊因為是處於上層的JAVA部分,且僅負責傳遞命令,所以選用了Intent的IPC傳輸方式;而我們在底層使用的方法,即為上期文章中所介紹的HAL技術,實作了接受車輛上OBD的相關服務,因為這是使用底層的服務,所以我們使用AIDL的機制,來讓OBD的服務與OSGI的Framework進行溝通,再將資訊遞送到內部的各個不同的核心程式Bundle去運作。透過這樣的機制,讓整個應用系統更加彈性也較易於維護。
【原文刊載於RUN!PC雜誌:2010年3月號】
回首頁...
關於RUN!PC
|
廣告刊登
|
聯絡我們
|
讀者服務
|
雜誌訂閱
|
出刊&補寄時間
-- Copyright© FLAG INFORMATION CO., LTD. 旗訊科技(股)公司. All rights reserved. 本站圖文著作權所有 未經授權 不得任意轉載使用 --
-- 請使用1024*768螢幕解析度,IE 7.0或firefox 3.0以上瀏覽器,以達到最佳閱讀效果--