很多人一提到Binder就說代理模式,人云亦云的多,能理解精髓的少。 本篇文章就從設計角度分析一下java層BInder的設計目標,以及設計思路,設計缺陷,從而駕馭它。 對於【邦德兒】的理解, 從通信的角度來看,就是一種通信方式而已,與socket沒有任何區別。客戶端transact,服務端onTr ...
很多人一提到Binder就說代理模式,人云亦云的多,能理解精髓的少。 本篇文章就從設計角度分析一下java層BInder的設計目標,以及設計思路,設計缺陷,從而駕馭它。
對於【邦德兒】的理解, 從通信的角度來看,就是一種通信方式而已,與socket沒有任何區別。客戶端transact,服務端onTransact. 但是,從【邦德兒】本身來說,如果客戶端和服務端在一個進程,那麼再通過底層驅動去把數據轉過去就顯得多餘了。基於這種理論,設計的時候,如果客戶端和服務端在一個進程就直接函數調用,而不再通過驅動。對於調用者來說,他只需要得到一個介面用來transact。並不願意知道具體的通信細節。也就是說,不關心是否是通過【邦德兒】驅動來傳輸的,還是直接在同進程通過函數的調用傳輸的。調用者確實不願意關心,調用者不願意關心的,那麼被調用者就得關心,不然代碼誰來寫。所以【邦德兒】本身必須要處理這兩種情況:
1.在同一個進程。這個對應的是Binder。
2.不在同一個進程。這個對應的是BInderProxy。
對於調用者來說,這兩個東西都實現了IBinder介面中的transact函數。BInderProxy通過底層驅動,把數據傳輸到服務端而BInder則直接通過內部調用轉給onTransact處理。
附註:
在這裡吐槽一下google。命名莫名其妙故弄玄虛。看到一個IBinder,腦子裡除了邦德兒之外沒有別的想法。我覺得,在設計上transact應該對應一個ISenderBinder,而onTransact對應一個IReceiverBinder。Binder實現了ISenderBinder和IReceiverBinder介面。這樣的邏輯才夠清晰。客戶端只要看到ISenderBinder就倍感親切,服務端只要看到IReceiverBinder就感覺自己在為別人做好事。一開始要做的事情就是打開通信通道,也就是把ISenderBinder這個東西對應的對象傳給客戶端。而服務端用誰進行服務都無所謂,只要是跟ISenderBinder是一對的就OK。BInderProxy應該叫做SenderBinder才合適。
那麼對於應用程式來說,他需要什麼?他需要函數調用,而不是transact這類東西。如果整天關心這些底層的打包解包那麼也就很頭大了。IActivityManager這個是用戶需要的介面,之前的transact介面明顯不合適讓用戶使用。把噁心的transact函數適配到IActivityManager。用戶用起來更好用了。既然是適配,那麼就有個介面轉換。一個叫做asInterface,一個叫做asBInder。網上一講這個東西就說是代理。這是其實是適配。asInterface將IBinder適配為IActivityManager。而asBInder將IActivityManager適配為IBinder。
google的代碼裡面,經常把這個能代表遠程對象的東西叫做代理。僅此而已。只要能代表遠程對象並執行函數。那麼就叫做代理。具體怎麼實現的,並不關心。在這裡代理只是一種脫離實際代碼的巨集願。