深刻解析 Android 的 AIDL 介面
在Android應(yīng)用框架裡,應(yīng)用層級(jí)的軟體大多是Java類別,而系統(tǒng)層級(jí)的軟體大多是C或 C++類別。Android使用JNI介面來達(dá)成這個(gè)目標(biāo)。例如,在Android裡有個(gè)MediaPlayer.cpp類別,當(dāng)它搭配上JNI介面之後,在VM上執(zhí)行的MediaPlayer.java就可以透過JNI介面與MediaPlayer.cpp類別溝通了。
圖1-1
基於這樣的架構(gòu),我門就可以盡量將MediaPlayer.java裡的程式邏輯移入MediaPlayer.cpp類別裡,以便加快程式的執(zhí)行速度。此外,以JNI介面包裝MediaPlayer.cpp類別,並且銜接相互輝映的MediaPlayer.java類別,可以讓眾多的Java應(yīng)用程式透過MediaPlayer.java來使用MediaPlayer.cpp類別的服務(wù)。這是一種非常有用的包裝技巧,藉由包裝來創(chuàng)造更多的應(yīng)用機(jī)會(huì)。
為了進(jìn)一步創(chuàng)造更多的應(yīng)用機(jī)會(huì),可以替MediaPlayer.java類別加上AIDL介面,讓更多的Java應(yīng)用程式能與MediaPlayer.java類別進(jìn)行遠(yuǎn)距的IPC溝通。如下圖所示:
圖1-2
上圖表示出JNI在Android裡扮演的角色,以及Android框架裡Java與C/C++類別融合的基本架構(gòu)。上面的圖1-2是一個(gè)較為抽象的圖,凸顯JNI與AIDL的相互呼應(yīng)之角色。
於此,以高煥堂所寫的第2本Android書:<<Android 軟體架構(gòu)設(shè)計(jì)>> 一書裡的範(fàn)例:HalfAdder組件為例,展示其幕後的細(xì)節(jié)架構(gòu)。首先看看其JNI介面之上的細(xì)節(jié)架構(gòu),如下UML圖:
圖1-3 上圖1-2幕後的細(xì)節(jié)架構(gòu)之一
上圖凸顯了AIDL介面的細(xì)節(jié)架構(gòu)。下圖1-4將換個(gè)角度,從*.so開發(fā)者來看,當(dāng)我們開發(fā)系統(tǒng)層級(jí)的C/C++類別時(shí),也能善用JNI,創(chuàng)造C/C++類別的廣大商機(jī)。其細(xì)節(jié)架構(gòu)如下UML圖:
圖1-4 上圖1-2幕後的細(xì)節(jié)架構(gòu)之二
1.3 說明C/C++組件開發(fā)
從上圖1-4可看到此範(fàn)例的C/C++組件部份。其詳細(xì)的程式碼,請(qǐng)閱讀高煥堂所寫的第2本Android書:<<Android 軟體架構(gòu)設(shè)計(jì)>> 一書之第5~6章。
1.4 說明AIDL介面類別之開發(fā)
基於剛才所撰寫的相對(duì)應(yīng)Java類別:Calculator.java,就能順利配上AIDL介面了。
1.4.1 細(xì)說AIDL介面與IBinder介面
其實(shí),AIDL介面幕後是仰賴著IBinder介面的。所以,我們的應(yīng)用程式可以選擇使用IBinder介面,也可以使用AIDL介面。如果採取IBinder介面,就不必使用aidl.exe工具去產(chǎn)出calInterface.java介面定義檔了,其介面類別較單純一些,如下圖所示:
圖1-5 僅使用較單純的IBinder介面
由於IBinder介面只提供單一函數(shù)(即transact()函數(shù))來進(jìn)行遠(yuǎn)距溝通,呼叫起來比較不方便。例如,當(dāng)Calculator類別有多個(gè)函數(shù)時(shí),myActivity要如何呼叫它們呢? 可以呼叫IBinder介面的transact()函數(shù),再轉(zhuǎn)而呼叫Calculator的各個(gè)函數(shù)。由於它並不太方便,所以Android提供Proxy/Stub結(jié)構(gòu)的AIDL介面來化解這個(gè)問題,其架構(gòu)圖如下:
圖1-6 更方便的AIDL介面(其介面類別結(jié)構(gòu)較複雜一些)
在本範(fàn)例裡,將採取AIDL介面,同時(shí)也介紹其幕後的IBinder介面,以及其兩這之間的密切關(guān)係。
聯(lián)系客服