<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>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                defaultServiceManager函數的實現在IServiceManager.cpp中完成。它會返回一個IServiceManager對象,通過這個對象,我們可以神奇地與另一個進程ServiceManager進行交互。是不是有一種觀看時空穿越魔術表演的感覺? 1. 魔術前的準備工作 先來看看defaultServiceManager都調用了哪些函數?返回的這個IServiceManager到底是什么?具體實現代碼如下所示: **IServiceManager.cpp** ~~~ sp<IServiceManager> defaultServiceManager() { //看樣子又是一個單例,英文名叫 Singleton,Android是一個優秀的源碼庫,大量使用了 //設計模式,建議讀者以此為契機學習設計模式,首推GOF的《設計模式:可復用面向對象軟件的基礎》 if(gDefaultServiceManager != NULL) return gDefaultServiceManager; { AutoMutex _l(gDefaultServiceManagerLock); if(gDefaultServiceManager == NULL) { //真正的gDefaultServiceManager是在這里創建的。 gDefaultServiceManager = interface_cast<IServiceManager>( ProcessState::self()->getContextObject(NULL)); } } returngDefaultServiceManager; } ~~~ 哦,是調用了ProcessState的getContextObject函數!注意:傳給它的參數是NULL,即0。既然是“庖丁解牛”,就還要一層一層往下切。下面再看getContextObject函數,如下所示: **ProcessState.cpp** ~~~ sp<IBinder>ProcessState::getContextObject(const sp<IBinder>& caller) { /* caller的值為0!注意,該函數返回的是IBinder。它是什么?我們后面再說。 supportsProcesses函數根據openDriver函數打開設備是否成功來判斷是否支持process 真實設備肯定支持process。 */ if(supportsProcesses()) { //真實設備上肯定是支持進程的,所以會調用下面這個函數 return getStrongProxyForHandle(0); } else { return getContextObject(String16("default"), caller); } } ~~~ getStrongProxyForHandle這個函數名怪怪的,可能會讓人感到些許困惑。請注意,它的調用參數的名字叫handle,Windows編程中經常使用這個名稱,它是對資源的一種標識。說白了,其實就是有一個資源項,保存在一個資源數組(也可以是別的組織結構)中,handle的值正是該資源項在數組中的索引。 **ProcessState.cpp** ~~~ sp<IBinder>ProcessState::getStrongProxyForHandle(int32_t handle) { sp<IBinder> result; AutoMutex_l(mLock); /* 根據索引查找對應資源。如果lookupHandleLocked發現沒有對應的資源項,則會創建一個新的項并返回。 這個新項的內容需要填充。 */ handle_entry* e = lookupHandleLocked(handle); if (e !=NULL) { IBinder* b = e->binder; if (b== NULL || !e->refs->attemptIncWeak(this)) { //對于新創建的資源項,它的binder為空,所以走這個分支。注意,handle的值為0 b= new BpBinder(handle); //創建一個BpBinder e->binder = b; //填充entry的內容 if (b) e->refs = b->getWeakRefs(); result = b; }else { result.force_set(b); e->refs->decWeak(this); } } returnresult; //返回BpBinder(handle),注意,handle的值為0 } ~~~ 2. 魔術表演的道具——BpBinder 眾所周知,玩魔術是必須有道具的。這個穿越魔術的道具就是BpBinder。BpBinder是什么呢?有必要先來介紹它的孿生兄弟BBinder。 BpBinder和BBinder都是Android中與Binder通信相關的代表,它們都從IBinder類中派生而來,如圖6-2所示: :-: ![](http://img.blog.csdn.net/20150802155849603?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center) 圖6-2 Binder家族圖譜 從上圖中可以看出: - BpBinder是客戶端用來與Server交互的代理類,p即Proxy的意思。 - BBinder則是proxy相對的一端,它是proxy交互的目的端。如果說Proxy代表客戶端,那么BBinder則代表服務端。這里的BpBinder和BBinder是一一對應的,即某個BpBinder只能和對應的BBinder交互。我們當然不希望通過BpBinderA發送的請求,卻由BBinderB來處理。 剛才我們在defaultServiceManager()函數中創建了這個BpBinder。這里有兩個問題: - 為什么創建的不是BBinder? 因為我們是ServiceManager的客戶端,當然得使用代理端以與ServiceManager交互了。 - 前面說了,BpBinder和BBinder是一一對應的,那么BpBinder如何標識它所對應的BBinder端呢? 答案是Binder系統通過handler來對應BBinder。以后我們會確認這個Handle值的作用。 * * * * * **注意**:我們給BpBinder構造函數傳的參數handle的值是0。這個0在整個Binder系統中有重要含義—因為0代表的就是ServiceManager所對應的BBinder。 * * * * * BpBinder是如此重要,必須對它進行深入分析,其代碼如下所示: **BpBinder.cpp** ~~~ BpBinder::BpBinder(int32_t handle) :mHandle(handle)//handle是0 ,mAlive(1) ,mObitsSent(0) ,mObituaries(NULL) { extendObjectLifetime(OBJECT_LIFETIME_WEAK); //另一個重要對象是IPCThreadState,我們稍后會詳細講解。 IPCThreadState::self()->incWeakHandle(handle); } ~~~ 看上面的代碼,會覺得BpBinder確實簡單,不過再仔細查看,你或許會發現,BpBinder、BBinder這兩個類沒有任何地方操作ProcessState打開的那個/dev/binder設備,換言之,這兩個Binder類沒有和binder設備直接交互。那為什么說BpBinder會與通信相關呢?注意本小節的標題,BpBinder只是道具嘛!所以它后面一定還另有機關。不必急著揭秘,還是先回顧一下道具出場的歷程。 我們是從下面這個函數開始分析的: ~~~ gDefaultServiceManager =interface_cast<IServiceManager>( ProcessState::self()->getContextObject(NULL)); ~~~ 現在這個函數調用將變成如下所示: ~~~ gDefaultServiceManager =interface_cast<IServiceManager>(new BpBinder(0)); ~~~ 這里出現了一個interface_cast。它是什么?其實是一個障眼法!下面就來具體分析它。 3. 障眼法——interface_cast interface_cast、dynamic_cast和static_cast看起來是否非常眼熟?它們是指針類型轉換的意思嗎?如果是,那又是如何將BpBinder*類型強制轉化成IServiceManager*類型的?BpBinder的家譜我們剛才也看了,它的“爸爸的爸爸的爸爸”這條線上沒有任何一個與IServiceManager有任何關系。 問題談到這里,我們得去看看interface_cast的具體實現,其代碼如下所示: **IInterface.h** ~~~ template<typename INTERFACE> inline sp<INTERFACE> interface_cast(constsp<IBinder>& obj) { returnINTERFACE::asInterface(obj); } ~~~ 哦,僅僅是一個模板函數,所以interface_cast<IServiceManager>()等價于: ~~~ inline sp<IServiceManager>interface_cast(const sp<IBinder>& obj) { return IServiceManager::asInterface(obj); } ~~~ 又轉移到IServiceManager對象中去了,這難道不是障眼法嗎?既然找到了“真身”,不妨就來見識見識它吧。 4. 撥開浮云見月明——IServiceManager 剛才提到,IBinder家族的BpBinder和BBinder是與通信業務相關的,那么業務層的邏輯又是如何巧妙地架構在Binder機制上的呢?關于這些問題,可以用一個絕好的例子來解釋,它就是IServiceManager。 (1)定義業務邏輯 先回答第一個問題:如何表述應用的業務層邏輯。可以先分析一下IServiceManager是怎么做的。IServiceManager定義了ServiceManager所提供的服務,看它的定義可知,其中有很多有趣的內容。IServiceManager定義在IServiceManager.h中,代碼如下所示: **IServiceManager.h** ~~~ class IServiceManager : public IInterface { public: //關鍵無比的宏! DECLARE_META_INTERFACE(ServiceManager); //下面是ServiceManager所提供的業務函數 virtualsp<IBinder> getService( constString16& name) const = 0; virtualsp<IBinder> checkService( constString16& name) const = 0; virtualstatus_t addService( const String16& name, const sp<IBinder>&service) = 0; virtual Vector<String16> listServices() = 0; ...... }; ~~~ (2)業務與通信的掛鉤 Android巧妙地通過DECLARE_META_INTERFACE和IMPLENT宏,將業務和通信牢牢地鉤在了一起。DECLARE_META_INTERFACE和IMPLEMENT_META_INTERFACE這兩個宏都定義在剛才的IInterface.h中。先看DECLARE_META_INTERFACE這個宏,如下所示: **IInterface.h::DECLARE_META_INTERFACE** ~~~ #define DECLARE_META_INTERFACE(INTERFACE) \ staticconst android::String16 descriptor; \ staticandroid::sp<I##INTERFACE> asInterface( \ const android::sp<android::IBinder>& obj); \ virtualconst android::String16& getInterfaceDescriptor() const; \ I##INTERFACE(); \ virtual~I##INTERFACE(); ~~~ 將IServiceManager的DELCARE宏進行相應的替換后得到的代碼如下所示: **DECLARE_META_INTERFACE(IServiceManager)** ~~~ //定義一個描述字符串 static const android::String16 descriptor; //定義一個asInterface函數 static android::sp< IServiceManager > asInterface(constandroid::sp<android::IBinder>& obj) //定義一個getInterfaceDescriptor函數,估計就是返回descriptor字符串 virtual const android::String16&getInterfaceDescriptor() const; //定義IServiceManager的構造函數和析構函數 IServiceManager (); virtual ~IServiceManager(); ~~~ DECLARE宏聲明了一些函數和一個變量,那么,IMPLEMENT宏的作用肯定就是定義它們了。IMPLEMENT的定義在IInterface.h中,IServiceManager是如何使用了這個宏呢?只有一行代碼,在IServiceManager.cpp中,如下所示: ~~~ IMPLEMENT_META_INTERFACE(ServiceManager,"android.os.IServiceManager"); ~~~ 很簡單,可直接將IServiceManager中的IMPLEMENT宏的定義展開,如下所示: ~~~ const android::String16 IServiceManager::descriptor(“android.os.IServiceManager”); //實現getInterfaceDescriptor函數 const android::String16& IServiceManager::getInterfaceDescriptor()const { //返回字符串descriptor,值是“android.os.IServiceManager” return IServiceManager::descriptor; } //實現asInterface函數 android::sp<IServiceManager> IServiceManager::asInterface(constandroid::sp<android::IBinder>& obj) { android::sp<IServiceManager> intr; if(obj != NULL) { intr = static_cast<IServiceManager *>( obj->queryLocalInterface(IServiceManager::descriptor).get()); if (intr == NULL) { //obj是我們剛才創建的那個BpBinder(0) intr = new BpServiceManager(obj); } } return intr; } //實現構造函數和析構函數 IServiceManager::IServiceManager () { } IServiceManager::~ IServiceManager() { } ~~~ 我們曾提出過疑問:interface_cast是如何把BpBinder指針轉換成一個IServiceManager指針的呢?答案就在asInterface函數的一行代碼中,如下所示: ~~~ intr = new BpServiceManager(obj); ~~~ 明白了!interface_cast不是指針的轉換,而是利用BpBinder對象作為參數新建了一個BpServiceManager對象。我們已經知道BpBinder和BBinder與通信有關系,這里怎么突然冒出來一個BpServiceManager?它們之間又有什么關系呢? (3)IServiceManager家族 要搞清這個問題,必須先了解IServiceManager家族之間的關系,先來看圖6-3,它展示了IServiceManager的家族圖譜。 :-: ![](http://img.blog.csdn.net/20150802155909525?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center) 圖6-3 IServiceManager的家族圖譜 根據圖6-3和相關的代碼可知,這里有以下幾個重要的點值得注意: - IServiceManager、BpServiceManager和BnServiceManager都與業務邏輯相關。 - BnServiceManager同時從BBinder派生,表示它可以直接參與Binder通信。 - BpServiceManager雖然從BpInterface中派生,但是這條分支似乎與BpBinder沒有關系。 - BnServiceManager是一個虛類,它的業務函數最終需要子類來實現。 >[info]重要說明:以上這些關系很復雜,但ServiceManager并沒有使用錯綜復雜的派生關系,它直接打開Binder設備并與之交互。后文,還會詳細分析它的實現代碼。 圖6-3中的BpServiceManager,既然不像它的兄弟BnServiceManager那樣直接與Binder有血緣關系,那么它又是如何與Binder交互的呢?簡言之,BpRefBase中的mRemote的值就是BpBinder。如果你不相信,仔細看BpServiceManager左邊的派生分支樹上的一系列代碼,它們都在IServiceManager.cpp中,如下所示: **IServiceManager.cpp::BpServiceManager類** ~~~ //通過它的參數可得知,impl是IBinder類型,看來與Binder有間接關系,它實際上是BpBinder對象 BpServiceManager(const sp<IBinder>& impl) //調用基類BpInterface的構造函數 : BpInterface<IServiceManager>(impl) { } ~~~ BpInterface的實現代碼如下所示: **IInterface.h::BpInterface類** ~~~ template<typename INTERFACE> inlineBpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote) :BpRefBase(remote)//基類構造函數 { } ~~~ BpRefBase()的實現代碼如下所示: **Binder.cpp::BpRefBase類** ~~~ BpRefBase::BpRefBase(const sp<IBinder>&o) //mRemote最終等于那個new 出來的BpBinder(0) :mRemote(o.get()), mRefs(NULL), mState(0) { extendObjectLifetime(OBJECT_LIFETIME_WEAK); if(mRemote) { mRemote->incStrong(this); mRefs= mRemote->createWeak(this); } } ~~~ 原來,BpServiceManager的一個變量mRemote是指向了BpBinder。至此,我們的魔術表演完了,回想一下defaultServiceManager函數,可以得到以下兩個關鍵對象: * 有一個BpBinder對象,它的handle值是0。 * 有一個BpServiceManager對象,它的mRemote值是BpBinder。 BpServiceManager對象實現了IServiceManager的業務函數,現在又有BpBinder作為通信的代表,接下來的工作就簡單了。下面,要通過分析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>

                              哎呀哎呀视频在线观看