Android插件化基礎(chǔ)--Binder機制

Binder是一套基于CS的架構(gòu)愿汰。下面以一個極簡的例子來學習Binder拄轻。

1.首先定義一個IMedia.aidl文件。
interface IMedia {
    boolean start();
    boolean stop();
}
2.然后IDE會幫我們自動生成一個IMedia.java文件
public interface IMedia extends android.os.IInterface {

        public static abstract class Stub extends android.os.Binder implements com.cmeiyuan.pluginstudy.IMedia {
                
                public android.os.IBinder asBinder(){
                    return this;
                }
                
                public static com.cmeiyuan.pluginstudy.IMedia asInterface(android.os.IBinder obj) {
                    ...
                }
                
                public boolean onTransact(...){
                    ...
                    start();
                    ...
                }
                
                private static class Proxy implements com.cmeiyuan.pluginstudy.IMedia {
                    ...
                }
        }
    }
    public boolean start() throws android.os.RemoteException;
}

IMedia是一個繼承于android.os.IInterface的接口,它的內(nèi)部類Stub實現(xiàn)了android.os.IInterfaceasBinder()方法,直接返回了Sub類實例缩擂。我們繼續(xù)看Sub類的asInterface()方法

public static com.cmeiyuan.pluginstudy.IMedia asInterface(android.os.IBinder obj) {
    if ((obj == null)) {
        return null;
    }
    android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
    if (((iin != null) && (iin instanceof com.cmeiyuan.pluginstudy.IMedia))) {
        return ((com.cmeiyuan.pluginstudy.IMedia) iin);
    }
    return new com.cmeiyuan.pluginstudy.IMedia.Stub.Proxy(obj);
}

這個方法的作用是將遠程Binder對象轉(zhuǎn)換為方便使用的IMedia接口對象,這個遠程Binder對象是我們bindService()時返回的添寺。首選通過obj.queryLocalInterface(DESCRIPTOR)查詢是否有本地接口對象胯盯,這種情況是當Server端和Client端處于同一進程,沒有必要進行多進程通信计露。如果沒有本地接口對象博脑,那么直接new一個Stub.Proxy(obj)實例返回。我們來看一下這個Proxy類的具體實現(xiàn)

private static class Proxy implements com.cmeiyuan.pluginstudy.IMedia {
    private android.os.IBinder mRemote;

    Proxy(android.os.IBinder remote) {
        mRemote = remote;
    }
    
    @Override
    public boolean start() throws android.os.RemoteException {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        boolean _result;
        try {
            _data.writeInterfaceToken(DESCRIPTOR);
            mRemote.transact(Stub.TRANSACTION_start, _data, _reply, 0);
            _reply.readException();
            _result = (0 != _reply.readInt());
        } finally {
            _reply.recycle();
            _data.recycle();
        }
        return _result;
    }
}

這個Proxy類是Stub類的內(nèi)部類票罐,其實就是對obj的一層封裝(代理)叉趣,那么我們通過這個代理類,就很容易和Server端進行通信了该押。具體實現(xiàn)也很簡單疗杉,就是調(diào)用遠程Binder對象mRemotetransact()方法,將數(shù)據(jù)發(fā)送給Server端蚕礼。

Stub是一個抽象類烟具,繼承于Binder類,實現(xiàn)了父類的onTransact()方法奠蹬,onTransact()方法的作用是執(zhí)行Server端的操作朝聋,并將操作的結(jié)果返回給Client端。一般情況囤躁,我們需要寫一個子類繼承于Stub類冀痕,然后實現(xiàn)IMedia的接口方法,這些方法會被父類onTransact()方法調(diào)用到狸演。

3.總結(jié)一下多進程通信過程:

(1)通過bindService()得到遠程Binder對象obj
(2)通過IMedia.Stub.asInterface(obj)得到一個遠程代理類Sub.Proxy對象mediaRemoteProxy
(3)調(diào)用mediaRemoteProxy.start()方法言蛇,事實上是調(diào)用了其內(nèi)部遠程Binder對象mRemotetransact()方法,將數(shù)據(jù)發(fā)送給Server
(4)服務(wù)端收到Client端發(fā)送過來的數(shù)據(jù)時onTransact()會被調(diào)用严沥,有一個子類繼承于IMedia.Stub類猜极,實現(xiàn)了start()方法,onTransact()被調(diào)用時消玄,自然調(diào)用到了子類里的start()方法跟伏。換言之,Server端的操作被Client調(diào)用執(zhí)行了翩瓜。

4.start()方法是在哪個線程被執(zhí)行的
private IMedia.Stub stub = new IMedia.Stub() {
    @Override
    public boolean start() throws RemoteException {
        Log.d("cmy", "media start:" + Thread.currentThread().getId());
        return true;
    }
};

通過調(diào)試程序發(fā)現(xiàn)start()方法被執(zhí)行在名為binder1binder2的線程中受扳,而不是主線程。這也解釋了系統(tǒng)的ActivityManagerService向應用進程發(fā)送消息時兔跌,需要使用H類把消息轉(zhuǎn)發(fā)到UI線程勘高,而且也必須這么做,因為UI線程調(diào)用了Looper.loop()開啟了循環(huán),線程是被阻塞的华望。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蕊蝗,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子赖舟,更是在濱河造成了極大的恐慌蓬戚,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,366評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件宾抓,死亡現(xiàn)場離奇詭異子漩,居然都是意外死亡,警方通過查閱死者的電腦和手機石洗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評論 3 395
  • 文/潘曉璐 我一進店門幢泼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人讲衫,你說我怎么就攤上這事缕棵。” “怎么了涉兽?”我有些...
    開封第一講書人閱讀 165,689評論 0 356
  • 文/不壞的土叔 我叫張陵挥吵,是天一觀的道長。 經(jīng)常有香客問我花椭,道長,這世上最難降的妖魔是什么房午? 我笑而不...
    開封第一講書人閱讀 58,925評論 1 295
  • 正文 為了忘掉前任矿辽,我火速辦了婚禮,結(jié)果婚禮上郭厌,老公的妹妹穿的比我還像新娘袋倔。我一直安慰自己,他們只是感情好折柠,可當我...
    茶點故事閱讀 67,942評論 6 392
  • 文/花漫 我一把揭開白布宾娜。 她就那樣靜靜地躺著,像睡著了一般扇售。 火紅的嫁衣襯著肌膚如雪前塔。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,727評論 1 305
  • 那天承冰,我揣著相機與錄音华弓,去河邊找鬼。 笑死困乒,一個胖子當著我的面吹牛寂屏,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,447評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼迁霎,長吁一口氣:“原來是場噩夢啊……” “哼吱抚!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起考廉,我...
    開封第一講書人閱讀 39,349評論 0 276
  • 序言:老撾萬榮一對情侶失蹤秘豹,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后芝此,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體憋肖,經(jīng)...
    沈念sama閱讀 45,820評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,990評論 3 337
  • 正文 我和宋清朗相戀三年婚苹,在試婚紗的時候發(fā)現(xiàn)自己被綠了岸更。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,127評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡膊升,死狀恐怖怎炊,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情廓译,我是刑警寧澤评肆,帶...
    沈念sama閱讀 35,812評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站非区,受9級特大地震影響瓜挽,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜征绸,卻給世界環(huán)境...
    茶點故事閱讀 41,471評論 3 331
  • 文/蒙蒙 一久橙、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧管怠,春花似錦淆衷、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至她肯,卻和暖如春佳头,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背晴氨。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評論 1 272
  • 我被黑心中介騙來泰國打工畜晰, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人瑞筐。 一個月前我還...
    沈念sama閱讀 48,388評論 3 373
  • 正文 我出身青樓凄鼻,卻偏偏與公主長得像腊瑟,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子块蚌,可洞房花燭夜當晚...
    茶點故事閱讀 45,066評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 原文:http://weishu.me/2016/01/12/binder-index-for-newer/ 要點...
    指尖流逝的青春閱讀 2,609評論 0 13
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理闰非,服務(wù)發(fā)現(xiàn),斷路器峭范,智...
    卡卡羅2017閱讀 134,667評論 18 139
  • 原文鏈接: http://weishu.me/2016/01/12/binder-index-for-newer/...
    miniminiming閱讀 726評論 1 6
  • 毫不夸張地說财松,Binder是Android系統(tǒng)中最重要的特性之一;正如其名“粘合劑”所喻纱控,它是系統(tǒng)間各個組件的橋梁...
    weishu閱讀 17,870評論 29 246
  • 不知你有沒有過這樣的感覺甜害,每每在一件事上追趕上別人舶掖,還沒來得及興奮和激動,就發(fā)現(xiàn)自己又落后了尔店。 這種相比較的落后無...
    茶幾醬閱讀 226評論 0 0