Binder機制是Android系統進程間通信的核心機制,它很大而且很復雜,不過對它有一定程度的理解和掌握是真正接觸
Android核心的必備。網上關於它的介紹很多,希望大家能耐著性子認真地學習Binder機制的實現。在此 寫點關於Binder機制的,但無奈自己的理解程度還很膚淺,只好放棄了。
自己從事的模塊開發采用了Binder機制進行功能的開發,對Binder機制的不熟悉,導致了很多Bug的出現,可謂“一Bug
未解,一Bug又起”,傷腦筋。今天對Binder運用過程中可能出現的兩個問題做下總結,希望幫大家有所啟發。
為了下面敘述的清楚,假設我們存在如下的Binder交互對象:
1 、 binderDied()方法的觸發時機
當客戶端對象A死掉時或者其他情況導致該Binder發生結束了,就會回調binderDied()方法,用戶可以在這個方法裡
進行捕捉binder死掉。
其方法原型在:IBinder.h文件中 (frameworks/base/include/binder/Ibinder.h)
[java]
- /**
- * This method allows you to add data that is transported through
- * IPC along with your IBinder pointer. When implementing a Binder
- * object, override it to write your desired data in to @a outData.
- * You can then call getConstantData() on your IBinder to retrieve
- * that data, from any process. You MUST return the number of bytes
- * written in to the parcel (including padding).
- */
- class DeathRecipient : public virtual RefBase
- {
- public:
- virtual void binderDied(const wp<IBinder>& who) = 0;
- };
通常而言,我們可以在服務端BnXXX 裡實現該虛函數去捕獲Binder死掉事件,例如:
[java]
- //Binder機制服務端的具體實現類
- class BnXXX: public BnInterface<IXX>
- {
- public:
- virtual status_t onTransact( uint32_t code,
- const Parcel& data,
- Parcel* reply,
- uint32_t flags = 0);
-
- //當Binder機制的客戶端死掉,導致了該Binder結束,會回調此方法
- void FMRadio::binderDied(const wp<IBinder>& who) {
- //輸出該Binder進程所在的信息 包括進程Id(pid)等
- LOGD("binderDied() 1 %p, tid %d, calling tid %d", who.unsafe_get(), gettid(),
- IPCThreadState::self()->getCallingPid());
- // do something
- }
- }
2、 Unknown binder error code 0xfffffff7 出現的原因。
當客戶端與服務端正在通過Binder機制交互時,例如A正在通過Binder機制與B對象進行交互,即A請求B do something,
這個過程中如果Binder機制發生了異常,導致A與B的交互不能正常進行,例如代碼中顯示調用System.exit(0)結束應用程序
(說明:System.exit(0)方法會 清空該Process的一切資源,包括Activity、Service、BroadcastReceiver等資源,Binder交互
也結束),系統就打印如下Log信息:“Error: JavaBinder Unknown binder error code. 0xfffffff7”。接下來,C++層會調用
binderDied() 方法,其Binder客戶端也死掉了,。
最後,希望大家在此基礎上能少找些彎路,多解幾個Bug吧 ,善莫大焉 !