日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

Android進(jìn)程間Binder機(jī)制服務(wù)端及客戶端C 實(shí)現(xiàn)分析

 arm_embed 2012-07-20


接觸過android的人都知道Binder服務(wù)調(diào)用是android系統(tǒng)的基礎(chǔ)。它擔(dān)負(fù)是跨進(jìn)程或進(jìn)程內(nèi)調(diào)用和數(shù)據(jù)傳遞的任務(wù)。理解它是理解android眾多services的基礎(chǔ)。binder服務(wù)的層次圖如下:

從圖中看出,一個(gè)binder服務(wù)基本分為3層:第一層業(yè)務(wù)層,它是服務(wù)的主體;第二層是粘合層,它把服務(wù)的主體和下層的binder層粘合在一起,在這一層上,可以進(jìn)行transact()調(diào)用;第三層是binder層,它負(fù)責(zé)與binder驅(qū)動(dòng)交互,完成跨進(jìn)程數(shù)據(jù)傳遞。下面從服務(wù)端實(shí)現(xiàn)說起:

Binder服務(wù)的C++實(shí)現(xiàn)分析
BnXXXService是由模板類BnInterface生成的,BnInterface扮演粘合劑的角色,它把服務(wù)主體接口(IXXXService)和服務(wù)載體(BBinder)粘和在一起。它定義在frameworks/base/include/binder/IInterface.h:
  1. template<typename INTERFACE>
  2. class BnInterface : public INTERFACE, public BBinder
  3. {
  4. public:
  5.     virtual sp<IInterface> queryLocalInterface(const String16& _descriptor);
  6.     virtual const String16& getInterfaceDescriptor() const;

  7. protected:
  8.     virtual IBinder* onAsBinder();
  9. };

一個(gè)新的服務(wù)實(shí)體類BnXXXService一般用下面的方式定義:

  1. class BnXXXService : public BnInterface<IXXXService>
  2. {
  3. public:
  4.     virtual status_t onTransact( uint32_t code,
  5.                                     const Parcel& data,
  6.                                     Parcel* reply,
  7.                                     uint32_t flags = 0);
  8. };

模板展開后,相當(dāng)于:
  1. class BnXXXService : public IXXXService, public BBinder{
  2. public:
  3.     virtual status_t onTransact( uint32_t code,
  4.                                     const Parcel& data,
  5.                                     Parcel* reply,
  6.                                     uint32_t flags = 0);
  7. }
這樣BnXXXService同時(shí)繼承于IXXXService和BBinder。IXXXService是服務(wù)的接口,具體的服務(wù)函數(shù)在BnXXXService中實(shí)現(xiàn)。必須重載BnXXXService::onTransact(),在其中對不同的請求code,調(diào)用不同的函數(shù)。BBinder是服務(wù)的載體。當(dāng)客戶端發(fā)起服務(wù)請求,binder驅(qū)動(dòng)找出相應(yīng)服務(wù)的binder對象,這個(gè)binder對象就是BBinder,返回給IPCThreadState,IPCThreadState調(diào)用BBinder::transact(),如下面1028行代碼所示:
  1. 891 status_t IPCThreadState::executeCommand(int32_t cmd){
  2. ...
  3. 897 switch (cmd) {
  4. ....
  5. 970 case BR_TRANSACTION:
  6. 971 {
  7. 972     binder_transaction_data tr;
  8. 973     result = mIn.read(&tr, sizeof(tr));
  9.         ....
  10. 1026    if (tr.target.ptr) {
  11. 1027        sp<BBinder> b((BBinder*)tr.cookie);
  12. 1028        const status_t error = b->transact(tr.code, buffer, &reply, tr.flags);
  13. 1029        if (error < NO_ERROR) reply.setError(error);
  14. 1030
  15. 1031     } else {
  16.             ....
  17. 1034 }
  18. }

1028行調(diào)用BBinder::tranact()。BBinder::tranact()是:

  1. 96 status_t BBinder::transact(
  2. 97 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
  3. 98 {
  4. 99     data.setDataPosition(0);
  5. 100
  6. 101     status_t err = NO_ERROR;
  7. 102     switch (code) {
  8.         ....
  9. 106     default:
  10. 107         err = onTransact(code, data, reply, flags);
  11. 108         break;
  12. 109     }
  13.         ....
  14. 115     return err;
  15. 116 }

107行調(diào)用的onTransact(),其實(shí)就是BnXXXService::onTransact()。這樣就可以在BnXXXService::onTransact()中通過switch語句完成各種各樣的服務(wù)。有關(guān)類的關(guān)系如圖:


由此看出:BnXXXService包含兩部分:一是IXXXService,服務(wù)的主體的接口;另一部分是BBinder,它是服務(wù)的載體,它和binder驅(qū)動(dòng)共同工作,保證客戶的請求最終是對一個(gè)binder對象(BBinder類)的調(diào)用。從binder驅(qū)動(dòng)的角度,每一個(gè)服務(wù)就是一個(gè)BBinder類,binder驅(qū)動(dòng)負(fù)責(zé)找出服務(wù)對應(yīng)的BBinder類。然后把這個(gè)BBinder類返回給IPCThreadState,IPCThreadState調(diào)用BBinder的transact()。BBinder的transact()又會(huì)調(diào)用onTransact()。BBinder::onTransact()是虛函數(shù),所以實(shí)際實(shí)際是調(diào)用BnXXXService::onTransact(),這樣就可在BnXXXService::onTransact()中完成具體的服務(wù)函數(shù)的調(diào)用。

BnXXXService可以用下面的方法以名字“xxx.xxx.serviceName”向ServiceManager注冊:
  1. defaultServiceManager()->addService(String16("xxx.xxx.serviceName"), new BnXXXService());

注冊后,系統(tǒng)中的其他用戶就可以調(diào)用這個(gè)服務(wù)啦。

Binder客戶端C++實(shí)現(xiàn)分析

如果說BnInterface是服務(wù)端服務(wù)主體和載體的粘和劑,那么BpInterface就是客戶端代理和binder載體的粘合劑。它的定義:
  1. template<typename INTERFACE>
  2. class BpInterface : public INTERFACE, public BpRefBase
  3. {
  4. public:
  5.     BpInterface(const sp<IBinder>& remote);
  6. protected:
  7.     virtual IBinder* onAsBinder();
  8. };

與服務(wù)端類似,客服端一般也用下面的方式得到客戶端的服務(wù)代理:
  1. class BpXXXService: public BpInterface<IXXXService>{
  2. }

這樣BpXXXService實(shí)際上是
  1. class BpXXXService : public IXXXService, public BpRefBase{
  2. public:
  3.     BpXXXService(const sp<IBinder& remote);
  4. ....
  5. };

構(gòu)造BpXXXService時(shí)需要一個(gè)IBinder引用。這個(gè)引用從哪里來呢?下面這段代碼說明這個(gè)問題,它的功能是從ServiceManager得到注冊服務(wù)代理對象:
  1.     sp<IServiceManager> sm = defaultServiceManager();
  2.     sp<IBinder> binder = sm->getService(String16("IXXXService.name"));
  3.     sp<IXXXService> cs = interface_cast<IXXXService>(binder);

如代碼所示:先通過defaultServiceManager()得到IServiceManager的客戶代理,然后這個(gè)IServiceManager對象查詢"IXXXService.name"服務(wù),ServiceManager::getService()返回對應(yīng)服務(wù)的IBinder。最后,interface_cast把這個(gè)IBinder轉(zhuǎn)換成服務(wù)的客戶端代理類BpXXXService。interface_cast的定義如下,

  1. template<typename INTERFACE>
  2. inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
  3. {
  4.     return INTERFACE::asInterface(obj);
  5. }

  #define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)                     \
    const android::String16 I##INTERFACE::descriptor(NAME);             \
    const android::String16&                                            \
            I##INTERFACE::getInterfaceDescriptor() const {              \
        return I##INTERFACE::descriptor;                                \
    }                                                                   \
    android::sp<I##INTERFACE> I##INTERFACE::asInterface(                \
            const android::sp<android::IBinder>& obj)                   \
    {                                                                   \
        android::sp<I##INTERFACE> intr;                                 \
        if (obj != NULL) {                                              \
            intr = static_cast<I##INTERFACE*>(                          \
                obj->queryLocalInterface(                               \
                        I##INTERFACE::descriptor).get());               \
            if (intr == NULL) {                                         \
                intr = new Bp##INTERFACE(obj);                          \
            }                                                           \
        }                                                               \
        return intr;                                                    \
    }                                                                   \
    I##INTERFACE::I##INTERFACE() { }                                    \
    I##INTERFACE::~I##INTERFACE() { }                                   \

關(guān)鍵在:如果obj是BBinder,obj->queryLocalInterface()返回接口本身;如果是BpBinder,則返回NULL。利用這個(gè)特性,當(dāng)queryLocalInterface()返回NULL時(shí),程序構(gòu)造一個(gè)BpXXXService。這就是interface_cast(const sp<IBinder>& obj)返回的客戶端代理類BpXXXService。

這里有個(gè)細(xì)節(jié),binder驅(qū)動(dòng)實(shí)際上返回的是服務(wù)的句柄(handle),而getService返回的是IBinder。這中間發(fā)生了什么?看看getService(),getSerivice()調(diào)用checkService():
  1. virtual sp<IBinder> checkService( const String16& name) const
  2. {
  3.     Parcel data, reply;
  4.     data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
  5.     data.writeString16(name);
  6.     remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);
  7.     return reply.readStrongBinder();
  8. }
CHECK_SERVICE_TRANSACTION的結(jié)果放在reply,binder驅(qū)動(dòng)返回的服務(wù)句柄放在reply中,它應(yīng)該在Parcel::readStrongBinder()中被轉(zhuǎn)換成sp<IBinder>。看看Parcel::readStrongBinder()
  1. sp<IBinder> Parcel::readStrongBinder() const
  2. {
  3.     sp<IBinder> val;
  4.     unflatten_binder(ProcessState::self(), *this, &val);
  5.     return val;
  6. }
  7. ...
  8. status_t unflatten_binder(const sp<ProcessState>& proc,
  9.     const Parcel& in, sp<IBinder>* out)
  10. {
  11.     const flat_binder_object* flat = in.readObject(false);
  12.     
  13.     if (flat) {
  14.         switch (flat->type) {
  15.             case BINDER_TYPE_BINDER:
  16.                 *out = static_cast<IBinder*>(flat->cookie);
  17.                 return finish_unflatten_binder(NULL, *flat, in);
  18.             case BINDER_TYPE_HANDLE:
  19.                 *out = proc->getStrongProxyForHandle(flat->handle);
  20.                 return finish_unflatten_binder(
  21.                     static_cast<BpBinder*>(out->get()), *flat, in);
  22.         }
  23.     }
  24.     return BAD_TYPE;
  25. }
Parcel::readStrongBinder()調(diào)unflatten_binder()。在unflatten_binder()里,由于binder驅(qū)動(dòng)返回的是handle,所以ProcessState::getStrongProxyForHandle()被調(diào)用。
  1. sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
  2. {
  3.     sp<IBinder> result;

  4.     AutoMutex _l(mLock);

  5.     handle_entry* e = lookupHandleLocked(handle);

  6.     if (e != NULL) {
  7.         IBinder* b = e->binder;
  8.         if (b == NULL || !e->refs->attemptIncWeak(this)) {
  9.             b = new BpBinder(handle); /*以handle為參數(shù)構(gòu)造BpBinder*/ e->binder = b;
  10.             if (b) e->refs = b->getWeakRefs();
  11.             result = b;
  12.         } else {
  13.             ....
  14.         }
  15.     }
  16.     return result;
  17. }
如果應(yīng)用是第一次請求服務(wù),那lookupHandleLocked(handle)應(yīng)該返回Null 。這樣ProcessState::getStrongProxyForHandle()構(gòu)造一個(gè)以handle為參數(shù)構(gòu)造BpBinder。這個(gè)BpBinder就是getService()得到IBinder。這樣這個(gè)至關(guān)重要的handle被保存在BpBinder里。這個(gè)BpBinder也是interface_cast(const sp<IBinder>& obj)中輸入?yún)?shù)的IBinder。
客戶端涉及的類關(guān)系圖:

到此為止,我們大致勾畫出binder調(diào)用的過程,服務(wù)端用BnInterface模板,把具體服務(wù)的接口和BBinder結(jié)合起來生成一個(gè)服務(wù)類。然后把這個(gè)服務(wù)類向ServiceManager注冊,注冊簡單地說就是把一個(gè)服務(wù)的名字和它對應(yīng)的BBinder的句柄(handle)在ServiceManager中關(guān)聯(lián)起來。以后有人需要這個(gè)服務(wù),可以用名字得到它的句柄,用這個(gè)句柄,binder驅(qū)動(dòng)就可以找到具體的BBinder服務(wù)類了。
客戶端用BpInterface模板,把具體服務(wù)的接口和BpBinder結(jié)合起來生成一個(gè)客戶端代理類。客戶端代理類的實(shí)質(zhì)就是一個(gè)服務(wù)句柄,這個(gè)句柄從binder驅(qū)動(dòng)中返回給應(yīng)用層,應(yīng)用層再用Parcel::readStrongBinder()把它轉(zhuǎn)換成sp<IXXXService>,并把它保存在BpBinder。

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多