android主板接口定义,范例解析:学习Android的IPC主板模式
一、認(rèn)識(shí)Android的IPC主板模式
系統(tǒng)架構(gòu)設(shè)計(jì)最關(guān)鍵的任務(wù)就是組合(或稱(chēng)整合),而且最好是能與眾不同、深具創(chuàng)新性組合。Android就擅用了主板模式,以通用性接口實(shí)踐跨進(jìn)程的IPC通信機(jī)制。由于Android是開(kāi)源開(kāi)放的系統(tǒng),其源代碼可成為大家觀摩的范本。首先,其主板模式提供了IBinder通用性接口。如下圖:
Android定義一個(gè)Binder父類(lèi)來(lái)實(shí)現(xiàn)的IBinder接口。如下圖:
然后,以Java來(lái)撰寫(xiě)這個(gè)實(shí)現(xiàn)類(lèi),其Java代碼如下:
// Android的源代碼
// Binder.java
// -------------------------------------------------------------
public?class?Binder?implements?IBinder?{
//?..........
private?int?mObject;
public?Binder()?{
init();
//其它代碼
}
public?final?boolean?transact(int?code,?Parcel?data,?Parcel?reply,??int?flags)
throws?RemoteException?{
//其它代碼
boolean?r?=?onTransact(code,?data,?reply,?flags);
return?r;
}
private?boolean?execTransact(int?code,?int?dataObj,?int?replyObj,?int?flags)?{
Parcel?data?=?Parcel.obtain(dataObj);
Parcel?reply?=?Parcel.obtain(replyObj);
boolean?res;
res?=?onTransact(code,?data,?reply,?flags);
//其它代碼
return?res;
}
protected?boolean?onTransact(int?code,?Parcel?data,?Parcel?reply,??int?flags)
throws?RemoteException?{
}
private?native?final?void?init();
}
// End
這個(gè)Binder抽象父類(lèi)的主要函數(shù):
transact()函數(shù)--用來(lái)實(shí)作IBinder的transact()函數(shù)接口。
execTransact()函數(shù)--其角色與transact()函數(shù)是相同的,只是這是用來(lái)讓C/C++本地程序來(lái)調(diào)用的。
onTransact()函數(shù)-- 這是一個(gè)抽象函數(shù),讓?xiě)?yīng)用子類(lèi)來(lái)覆寫(xiě)(Override)的。上述的transact()和execTransact()兩者都是調(diào)用onTransact()函數(shù)來(lái)實(shí)現(xiàn)反向調(diào)用(IoC,?Inversion?of?Control)的。
init()函數(shù)-- 這是一個(gè)本地(Native)函數(shù),讓JNI模塊來(lái)實(shí)現(xiàn)這個(gè)函數(shù)。Binder()構(gòu)造函數(shù)(Constructor)會(huì)調(diào)用這個(gè)init()本地函數(shù)。
這Binder.java是抽象類(lèi),它含有一個(gè)抽象)函數(shù):onTransact()。于是,這個(gè)軟件主板提供了兩個(gè)接口:CI和接口。如下圖:
這是標(biāo)準(zhǔn)型的主板模式。此圖里的Binder抽象父類(lèi)和兩個(gè)接口,整合起來(lái)成為一個(gè)典型的軟件主板。如下圖:
這個(gè)Binder軟件主板是用來(lái)整合兩個(gè)進(jìn)程里的軟件模塊(如類(lèi)),所以我們稱(chēng)之為:。如下圖:
基于這個(gè)主板,我們就能開(kāi)始進(jìn)行組合了。此時(shí),可設(shè)計(jì)一個(gè)子類(lèi),并且裝配到主板的接口上。如下圖:
這個(gè)IBinder接口是Binder基類(lèi)提供給Client的接口,簡(jiǎn)稱(chēng)為“CI”。于是,Client端調(diào)用IBinder接口的transact()函數(shù),進(jìn)而調(diào)用到Binder抽象類(lèi)的onTransact()函數(shù)。如果Client類(lèi)與Binder類(lèi)是執(zhí)行于同一個(gè)進(jìn)程里,Client端調(diào)用IBinder接口的transact()函數(shù),進(jìn)而調(diào)用到Binder抽象類(lèi)的onTransact()函數(shù)。反之,如果Client類(lèi)與Binder類(lèi)分別執(zhí)行于不同的兩個(gè)進(jìn)程里,Client端則調(diào)用Binder類(lèi)的exeTransact()函數(shù),透過(guò)IPC機(jī)制而調(diào)用到遠(yuǎn)方的onTransact()函數(shù)。例如,下圖里的Activity與Binder之間是跨進(jìn)程的遠(yuǎn)距通信(IPC)。如下圖:
Android的IPC機(jī)制是透過(guò)底層Binder驅(qū)動(dòng)來(lái)實(shí)現(xiàn)的,所以會(huì)從底層的C/C++函數(shù)來(lái)調(diào)用exeTransact()函數(shù),再轉(zhuǎn)而調(diào)用接口的onTransact()函數(shù)。如下圖:
Android跨進(jìn)程通信流程,都由底層Binder驅(qū)動(dòng)模塊所掌控。于是,Java層的Activity就能透過(guò)底層來(lái)調(diào)用Binder父類(lèi)的exeTransact()函數(shù)。如下圖所示:
二、主板模式與Proxy-Stub模式的組合應(yīng)用
在上圖里的Activity里可能有多個(gè)函數(shù),例如f1()和f2()等。于是,在Activity里,必須從f1()函數(shù)轉(zhuǎn)而調(diào)用IBinder.transact()函數(shù)。如果我們?cè)谏鲜黾軜?gòu)里面,加上一個(gè)Stub類(lèi)別(如下圖的BinderStub類(lèi)別),它實(shí)現(xiàn)了Binder.onTransact()函數(shù),如下圖所示:
通常,在框架設(shè)計(jì)里,myProxy和myStub會(huì)是成對(duì)的,這稱(chēng)為Proxy-Stub模式。如下圖所示:
采用Proxy-Stub設(shè)計(jì)模式將IBinder接口包裝起來(lái),讓App與IBinder接口不再產(chǎn)生高度相依性。其將IBinder接口包裝起來(lái),轉(zhuǎn)換出更好用的新接口,如下圖里的IA接口:
Stub類(lèi)將onTransact()函數(shù)隱藏起來(lái),提供一個(gè)更具有美感、更親切的新接口給subBinder類(lèi)使用。隱藏了onTransact()函數(shù)之后,subBinder類(lèi)的開(kāi)發(fā)者就不必費(fèi)心去了解onTransact()函數(shù)了。于是,Proxy與Stub兩個(gè)類(lèi)遙遙相對(duì),并且將IPC細(xì)節(jié)知識(shí)(例如transact()和onTransact()函數(shù)之參數(shù)等)包夾起來(lái)。由于IBinder接口只提供單一函數(shù)(即transact()函數(shù))來(lái)進(jìn)行遠(yuǎn)距通信,呼叫起來(lái)比較不方便。所以Android提供aidl.exe工具來(lái)協(xié)助產(chǎn)出Proxy和Stub類(lèi)別,以化解這個(gè)困難。只要你善于使用開(kāi)發(fā)環(huán)境的工具(如Android的aidl.exe軟件工具)自動(dòng)產(chǎn)生Proxy和Stub類(lèi)別的程序代碼;那就很方便了。◆
~ End ~
總結(jié)
以上是生活随笔為你收集整理的android主板接口定义,范例解析:学习Android的IPC主板模式的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: android汉字笔顺数据库,Chine
- 下一篇: android 随手记代码,用Expan