Android跨進程通信中Binder解析。
兩個接口
跨進程通訊中說到Binder和AIDL,就要說到最重要的兩個接口:IBinder和IInterface。
Binder具有被跨進程傳輸的能力是因為它實現瞭IBinder接口。系統會為每個實現瞭該接口的對象提供跨進程傳輸。那跨進程通信時,傳輸數據的媒介就是實現瞭IBinder的實例。
有瞭IBinder,IInterface又有啥用呢?我個人理解:這個接口隻是為瞭方面操作(隻有一個asbinder()方法嘛)。
那aidl文件和自動生成的同名的java文件是啥?aidl就是個接口咯,重點就在那個自動生成的java文件身上。這個java文件乍一看很大很亂,其實它的作用很簡單:還是方便操作(咳咳,有點官方瞭)。下面一段細說。
通信方式
將通信看成是進程A和進程B的通信。進程A看作客戶端,進程B看作服務器,我們想的通信過程:
1. 進程A將數據傳遞給進程B
2. 數據在進程B中進行處理
3. 進程A獲取處理後的數據
4. 完美
然而實際是這樣滴:
1. 進程B中定義實現瞭方法的Binder
2. 進程A獲取進程B的Binder
3. 進程A使用進程B的Binder來處理數據
假設A為一個Activity,B為一個Service。
A:有一個實現瞭IInterface的成員變量。一個ServiceConnection成員變量。ServiceConnection是用來接受從B中傳過來的Binder的。
B:一個Binder成員變量(比較特別的是,這個Binder類是實現瞭IInterface接口的子類)。
下面來分析aidl文件同名的java的類裡有啥呢:一個子類Stub(extends Binder, inplements自定義的接口),basicTypes()方法,未實現的自定義方法。
dang dang dang,這個Stub類就是上面說的傳遞的Binder。是不是說到這裡該結束瞭,其實並沒有。它的流程有點復雜,至於為什麼這麼復雜,其實我也不知道。(笑哭,以後分析)進程A獲取到的Binder並不是是這個Stub,而是Stub的一個代理/替身——Proxy。
跨進程用替身(代理)
Stub裡面有啥呢:asInterface()方法、asBinder()方法、onTransact()方法、Proxy類。Proxy是它的替身。asInterface是個static方法:如果兩個組件進程不同,那麼它返回Proxy;如果是同一進程,則返回自身。
替身套路與本身也不同,Proxy同樣也實現瞭aidl接口中的方法,而實現方法中其實還是調B的Stub的方法(通過onTransact進行調用)。