<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                前面一節我們分析了Binder通信相關的兩個重要類:ProcessState 和 IPCThreadState。ProcessState負責打開Binder 驅動,每個進程只有一個。而 IPCThreadState負責提供與Binder通信相關的接口,每個線程有一個。下面我們通過具體 示例MediaPlayerService來分析我們應用程序中怎么通過Binder通信的。 frameworks/base/media/mediaserver/main_mediaserver.cpp ~~~ int main(int argc, char*argv[]) { sp<ProcessState> proc(ProcessState)::self(); // 獲得ProcessState在構造函數中打開binder驅動 sp<IServiceManager> sm = defaultServiceManager(); MediaPlayService::instantiate(); ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool(); } ~~~ 1)獲得ServiceManager的代理BpServiceManager ~~~ sp<IServiceManager> sm = defaultServiceManager(); sp<IServiceManager> defaultServiceManager() { if(gDefaultServiceManager != NULL) return gDefaultServiceManager; { AutoMutex -l(gDefaultServiceManagerLock); if(gDefaultServiceManager == NULL) gDefaultServiceManager = interface_cast<IServiceManager>( ProcessState::self()->getContextObject(NULL)); } return gDefaultServiceManager; } ~~~ 這里又是一個單例模式,每個進程只需要一個BpServiceManager代理,通過interface_cast獲得。 首先看看ProcessState::self()->getContextObject(NULL) ~~~ sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller) { return getStrongProxyForHandle(0); } sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle) { sp<IBinder> result; AutoMutex _l(mLock); handle_entry *e = lookupHandleLocked(handle); if( e != NULL) { IBinder* b = e->binder; if(b == NULL || !e->refs->attemptIncWeak(this)) { b = new BpBinder(handle); e->binder = b; if(b) e->refs = b->getWeakRefs(); result = b; }else{ result.force_set(b); e->refs->decWeak(this); } } return result; } struct handle_entry{ IBinder* binder; RefBase::weakref_type* refs; } ~~~ ProcessState::handle_entry* ProcessState::lookupHandleLocked()從數組mHandleToObject里面根據handle索引,查找 一個handle_entry結構體。然后根據傳入的句柄handle這里為0,表示ServiceManager,new一個BpBinder 所以現在相當于: gDefaultServiceManager = interface_cast<IServiceManager>(new BpBinder(0)); 現在我們看看interface_cast是什么? ~~~ frameworks/base/include/binder/IInterface.h template<typename INTERFACE> inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj) { return INTERFACE::asInterface(obj); } 等價于: inline sp<IServiceManager> interface_cast(const sp<IBinder>& obj) { return IServiceManager::asInterface(obj); } 繼續我們跟到IServiceManager里面去: frameworks/base/include/binder/IServiceManager.h class IServiceManager:public IInterface { public: DECLARE_META_INTERFACE(ServiceManager);// MLGB的又是宏!!! virtual status_t addService(const String16& name, const sp<IBinder>& service) = 0; virtual sp<IBinder> getService(const String16& name) const = 0; } #define DECLARE_META_INTERFACE(INTERFACE) \ static const android::String16 descriptor; \ static android::sp<I##INTERFACE> asInterface( \ const android::sp<android::IBinder>& obj); \ virtual const android::String16& getInterfaceDescriptor() const;\ I##INTERFACE(); \ virtual !I##INTERFACE(); 替換之后就是: static const android::String16 descriptor; static android::sp<IServiceManager> asInterface( const android::sp<android::IBinder>& obj); virtual const android::String16& getInterfaceDescriptor() const; IServiceManager(); virtual !IServiceManager(); 都是一些函數聲明,既然有聲明的地方,肯定有實現的地方了。 #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() { } 繼續替換: { const android::String16 IServiceManager::descriptor(NAME); const android::String16& IServiceManager::getInterfaceDescriptor() const { return IServiceManager::descriptor; } android::sp<IServiceManager> IServiceManager::asInterface( const android::sp<android::IBinder>& obj) // 參數為new BpBinder(0) { android::sp<IServiceManager> intr; if (obj != NULL) { intr = static_cast<IServiceManager*>( obj->queryLocalInterface( IServiceManager::descriptor).get()); if (intr == NULL) { intr = new BpServiceManager(obj); // 原來在這里new 了一個BpServiceManager對象 } } return intr; } IServiceManager::IServiceManager() { } IServiceManager::~IServiceManager() { } } ~~~ 總結:根據句柄handle 0 創建一個new BpBinder(0),根據這個BpBinder創建了一個BpServiceManager代理。 下面來看看BpServiceManager代理: ~~~ class BpServiceManager : public BpInterface<IServiceManager> { public: BpServiceManager(const sp<IBinder>& impl) : BpInterface<IServiceManager>(iml) {} } ~~~ 這里BpInterface是一個模板類,表示這里BpServiceManager同時繼承與BpInterface和IServiceManager類 ~~~ template<typename INTERFACE> class BpInterface : public INTERFACE, public BpRefBase { public: BpInterface(const sp<IBinder>& remote); ... } 調用了基類BpInterface構造函數: BpInterface<IServiceManager>::BpInterace(const sp<IBinder>& remote) : BpRefBase(remote) {} //這里的remote就是剛剛的new BpBinder(0) BpRefBase::BpRefBase(const sp<IBinder>& o) : mRemote(o.get()),mRefs(NULL), mState(0) { } ~~~ 2)添加服務 MediaPlayerService::instantiate(); ~~~ frameworks/base/media/libmediaplayerservice/ibMediaPlayerService.cpp void MediaPlayerService::instantiate() { defaultServiceManager()->addService(String16("media.player"), new MediaPlayerService); } ~~~ defaultServiceManager()返回的是剛創建的BpServiceManager,調用add函數。 BpMediaPlayService作為服務代理端,那么BnMediaPlayerService一定是實現端,MediaPlayerService繼承于 BnMediaPlayerService,實現了真正的業務函數。 來看看BpServiceManager的addService()函數: ~~~ virtual status_t addService(const String16& name, const sp<IBinder>& service) { Parcel data, reply; data.writeInterfaceToken(IServiceManager.getInterfaceDescriptor()); // android.os.IServiceManager data.writeString16(name); // media.player data.writeStrongBinder(service); // 也就是MediaPlayerService status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply); return err == NO_ERROR ? reply.readInt32() : err; } ~~~ 這里remote()就是前面創建的BpBinder(0)對象。 ~~~ status_t BpBinder::transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { IPCThreadState::self()->transact(mHandle, code, data, reply, flags); } status_t IPCThreadState::transact(int32_t handle, uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { // 發送ADD_SERVICE_TRANSACTION請求 writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL); if(reply) // 等待響應 waitForResponse(NULL, reply); } status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags, int32_t handle, uint32_t code, const Parcel& data, status_t *statusBuffer) { // cmd BC_TRANSACTION 應用程序向BINDER發送的命令 binder_transaction_data tr; tr.target.handle = handle; // 0 tr.code = code; // ADD_SERVICE_TRANSACTION tr.flags = binderFlags; // 把命令和數據一起發送到 Parcel mOut中 mOut.writeInt32(cmd); mOut.write(&tr, sizeof(tr)); } status_t IPCThreadState::waitForResponse(Parcel* reply, status_t *acquireResult) { int32_t cmd; while(1) talkWithDriver(); cmd = mIn.readInt32(); switch(cmd) { case BR_TRANSACTION_COMPLETE: ... break; } { return err; } status_t IPCThreadState::talkWithDriver(bool doReceive) { binder_write_read bwr; bwr.write_size = outAvail; bwr.write_buf = (long unsigned int)mOut.data(); // 寫入mOut的數據 bwr.read_size = mIn.dataCapacity; bwr.read_buffer = (long unsigned int)mIn.data(); ioctl(mProcess->mDriverFD, BINDER_WRITE_READm &bwr); // 把mOut寫到Binder,并讀取mIn數據 } ~~~ 3)IPCThreadState::joinThreadPool(), ProcessState::self()->startThreadPool() 進入線程循環talkWithDriver 等待客戶端Client請求,從Binder讀取命令請求進行處理。 到現在為止MediaPlayerService的服務端已經向服務總管ServiceManager注冊了,下面我們看看客戶端是如何獲得服務的代理并和服務端通信的。 我們以MediaPlayer的業務函數decode解析播放一個URL為例 ~~~ sp<IMemory> MediaPlayer::decode(const char*url, uint32_t *pSampleRate, ...) { sp<IMemory> p; const sp<IMediaPlayerService>& service = getMediaPlayerService(); // 獲得BpMediaPlayerSerivce代理 if(service != 0) p = service->decode(url, ....); return p; } ~~~ 這里我們主要分析getMediaPlayerService,客戶端是如何向ServiceManager總管查詢服務并獲得代理的。 ~~~ sp<IMediaPlayerService>& IMediaDeathNotifier::getMediaPlayerService() { sp<IServiceManager> sm = defaultServiceManager(); // 生成一個BpServiceManager代理對象 sp<IBinder> binder; do { binder = sm->getService(String16("media.player")); if(binder != 0) break; usleep(500000) } while(true); sMediaPlayerService = interface_cast<IMediaPlayerService>(binder); return sMediaPlayerService; } ~~~ 1)首先獲得BpServiceManager的代理,然后調用getService()函數向服務總管ServiceManager查詢服務。 frameworks/base/libs/binder/IServiceManager.cpp ~~~ class BpServiceManager : public BpInterface<IServiceManager> { public: virtual sp<IBinder> getService(const String16& name) const { for(n = 0; n < 5; n++) { sp<IBinder> svc = checkService(name); // 調用checkService函數 if(svc != NULL) return svc; sleep(1); } return NULL; } virtual sp<IBinder> checkService(const String16& name) const { Parcel data, reply; data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor()); // 首先調用data.writeInt32(IPCThreadState::self()->getStrictModePolicy()) // 然后再寫入android.os.IServiceManager data.writeString16(name); // 寫入 media.player remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply); return reply.readStrongBinder(); } } ~~~ 這里首先將請求打包成Parcel各式,然后調用remote()->transact()函數,前面我們分析過BpServiceManager::remote()返回 的就是前面new BpBinder(0)對應句柄為ServiceManager。繼續去BpBinder中尋找實現代碼: frameworks/base/libs/binder/BpBinder.cpp ~~~ status_t BpBinder::transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { IPCThreadState::self()->transact(mHandle, code, data, reply, flags); } ~~~ 最后調用的IPCThreadState的transact()函數,IPCThreadState是專門提供通過Binder進程間通信的接口的。 ~~~ status_t IPCTheadState::transact(int32_t handle, uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { // 填充binder_transaction_data 結構體,寫入到mOut中去 writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL); // 調用talkWithDriver() 將mOut寫到Binder驅動,并從Binder驅動讀取mIn數據 waitForResponse(reply); } ~~~ 首先通過writeTransactionData函數來填充mOut結構體,mOut里面內容為: mOut.writeInt32(BC_TRANSACTION); mOut.write(&tr, sizeof(tr)); 這里binder_transaction_data tr內容為: tr.target.handle = 0;?// 表面是發往ServiceManager的 tr.code = CHECK_SERVICE_TRANSACTION; tr.flags = 0; tr.data內容為: data.writeInt32(IPCThreadState::self()->getStrictModePolicy() | STRICT_MODE_PENALTY_GATHER); data.writeString16("android.os.IServiceManager"); data.writeString16("media.player"); 根據前面Android開發之ServiceManager一章中我們分析,svcmgr_handler處理從句柄為0的Binder的請求: strict_policy = bio_get_string32(); s = bio_get_string16();?// 就是上面的android.os.IServiceManager s = bio_get_string16();?// 就是上面的 media.player 根據media.player遍歷全局鏈表svclist找到相應的服務,調用bio_put_ref(reply, ptr) 返回目標Binder實體。 這個waitForResponse()函數是關鍵: ~~~ status_t IPCThreadState::waitForResponse(Parcel* reply) { while(1) { talkWithDriver(); // 輸入mOut 輸出mIn cmd = mIn.readInt32(); switch(cmd) { case BR_REPLY: { binder_transaction_data tr; mIn.read(&tr, sizeof(tr)); if(reply) { reply->ipcSetDataReference(reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer), tr.data.size, reinterpret_cast<const size_t*>(tr.data.ptr.offsets), tr.offsets_size/sizeof(sizt_t), freeBuffer, this); } else { err = *static_cast<const status_t*>(tr.data.ptr.buffer); freeBuffer(NULL, reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer), tr.data.size, reinterpret_cast<const size_t*>(tr.data.ptr.offsets), tr.offsets_size/sizeof(sizt_t), freeBuffer, this) } } } } } 最后返回的是:return reply.readStrongBinder();進入到Parcel的readStrongBinder()函數 sp<IBinder> Parcel::readStrongBinder() const { sp<IBinder> val; unflatten_binder(ProcessState::self(), *this, &val); return val; } status_t unflatten_binder(const sp<ProcessState>& proc, const Parcel& in, sp<IBinder>* out) { const flat_binder_object* flat = in.readObject(false); if(flat) { switch(flat->type) { case BINDER_TYPE_BINDER: *out = static_cast<IBinder*>(flat->cookie); return finish_unflatten_binder(NULL, *flat, in); case BINDER_TYPE_HANDLE: *out = proc->getStrongProxyForHandle(flat->handle); return finish_unflatten_binder(static_cast<BpBinder*>(out->get()), *flat, in); } } } ~~~ 這里flat->type是BINDER_TYPE_HANDLE,所以調用ProcessState::getStrongProxyForHandle()函數 ~~~ sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle) { sp<IBinder> result; handle_entry* e = lookupHandleLocked(handle); if(e != NULL) { IBinder* b = e->binder; if(b == NULL || !e->refs->attemptIncWeak(this)) { b = new BpBinder(handle); e->binder = b; if( b ) e->refs = e->getWeakRefs(); result = b; } else { result.force_set(b); e->refs->decWeak(this); } } return result; } ~~~ 這里的handle就是ServiceManager內維護的MediaPlayerService對應的Binder句柄,這個ProcessState根據這個句柄 new 了一個BpBinder,并將其保存起來,這樣下次需要從ServiceManager請求獲取到相同句柄的時候就可以直接返回了。 最后根據這個返回的BpBinder獲得MediaPlayerService的代理: sMediaPlayerService = interface_cast<IMediaPlayerService>(binder); 根據前面ServiceManager一樣,最后調用的是IMediaPlayerService的asInterface()宏函數 ~~~ android::sp<IMediaPlayerService> IMediaPlayerService::asInterface(const android::sp<android::IBinder>& obj) { android::sp<IMediaPlayerService> intr; if(obj != NULL ) { intr = static_cast<IMediaPlayerService>( obj->queryLocalInterface(IMediaPlayerService::descriptor).get); if (intr == NULL) { intr = new BpMediaPlayerService(obj); } } return intr; } ~~~ 這樣我就獲得了一個代理BpMediaPlayerService對象,它的remote()為BpBinder(handle),這個handle就是向服務總共ServiceManager 查詢到的MediaPlayerService對應的Binder句柄。 下一章我們分析,客戶端如何通過這個BpServiceManager代理對象調用服務端MediaPlayerService的業務函數的?
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看