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