<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、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                這個例子源自ActivityManagerService,我們試圖通過它揭示Java層Binder的工作原理。先來描述一下該例子的分析步驟: - 首先分析AMS如何將自己注冊到ServiceManager。 - 然后分析AMS如何響應客戶端的Binder調用請求。 本例的起點是setSystemProcess,其代碼如下所示: **ActivityManagerService.java-->ActivityManagerService.setSystemProcess()** ``` public static void setSystemProcess() { try { ActivityManagerService m = mSelf; // 將ActivityManagerService服務注冊到ServiceManager中 ServiceManager.addService("activity", m);...... } catch {... } return; } ``` 上面所示代碼行的目的是將ActivityManagerService服務(以后簡稱AMS)加到ServiceManager中。 在整個Android系統中有一個Native的ServiceManager(以后簡稱SM)進程,它統籌管理Android系統上的所有Service。成為一個Service的首要條件是先在SM中注冊。下面來看Java層的Service是如何向SM注冊的。 #### 1. 向ServiceManager注冊服務 ##### (1)創建ServiceManagerProxy 向SM注冊服務的函數叫addService,其代碼如下: **ServiceManager.java-->ServiceManager.addService()** ``` public static void addService(String name, IBinderservice) { try { //getIServiceManager返回什么 getIServiceManager().addService(name, service); } ...... } ``` 首先需要搞清楚getIServiceManager()方法返回的是一個什么對象呢?參考其實現: **ServiceManager.java-->ServiceManager.getIServiceManager()** ``` private static IServiceManagergetIServiceManager() { ...... // 調用asInterface,傳遞的參數類型為IBinder sServiceManager = ServiceManagerNative.asInterface( BinderInternal.getContextObject()); returnsServiceManager; } ``` asInterface()方法的參數為BinderInternal.getContextObject()的返回值。于是這個簡短的方法中有兩個內容值得討論:BinderInternal.getContextObject()以及asInterface()。 BinderInternal.getContextObject()方法是一個native的函數,參考其實現: **android_util_Binder.cpp-->android_os_BinderInternal_getContextObject()** ``` static jobjectandroid_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz) { /* 下面這句代碼在卷I第6章詳細分析過,它將返回一個BpProxy對象,其中 NULL(即0,用于標識目的端)指定Proxy通信的目的端是ServiceManager*/ sp<IBinder> b = ProcessState::self()->getContextObject(NULL); // 由Native對象創建一個Java對象,下面分析該函數 returnjavaObjectForIBinder(env, b); } ``` 可見,Java層的ServiceManager需要在Native層獲取指向Native進程中ServiceManager的BpProxy。這個BpProxy不能由Java層的ServiceManager直接使用,于是android\_os\_BinderInteral\_getContextObject()函數通過javaObjectForIBinder()函數將創建一個封裝了這個BpProxy的一個Java對象并返回給調用者。ServiceManager便可一通過這個Java對象實現對BpProxy的訪問。參考這個Java對象的創建過程: **android_util_Binder.cpp-->javaObjectForIBinder()** ``` jobject javaObjectForIBinder(JNIEnv* env, constsp<IBinder>& val) { //mProxyLock是一個全局的靜態CMutex對象 AutoMutex _l(mProxyLock); /* val對象實際類型是BpBinder,讀者可自行分析BpBinder.cpp中的findObject函數。 事實上,在Native層的BpBinder中有一個ObjectManager,它用來管理在Native BpBinder 上創建的Java BpBinder對象。下面這個findObject用來判斷gBinderProxyOffsets 是否已經保存在ObjectManager中。如果是,那就需要刪除這個舊的object */ jobjectobject = (jobject)val->findObject(&gBinderProxyOffsets); if(object != NULL) { jobject res = env->CallObjectMethod(object,gWeakReferenceOffsets.mGet); android_atomic_dec(&gNumProxyRefs); val->detachObject(&gBinderProxyOffsets); env->DeleteGlobalRef(object); } // **① 創建一個新的BinderProxy對象。**并將它注冊到Native BpBinder對象的ObjectManager中 object =env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor); if(object != NULL) { /* ② 把Native層的BpProxy的指針保存到BinderProxy對象的成員字段mObject中。 于是BinderProxy對象的Native方法可以通過mObject獲取BpProxy對象的指針。 這個操作是將BinderProxy與BpProxy聯系起來的紐帶 */ env->SetIntField(object, gBinderProxyOffsets.mObject,(int)val.get()); val->incStrong(object); jobject refObject = env->NewGlobalRef( env->GetObjectField(object, gBinderProxyOffsets.mSelf)); /* 將這個新創建的BinderProxy對象注冊(attach)到BpBinder的ObjectManager中, 同時注冊一個回收函數proxy_cleanup。當BinderProxy對象撤銷(detach)的時候, 該函數會被調用,以釋放一些資源。讀者可自行研究proxy_cleanup函數*/ val->attachObject(&gBinderProxyOffsets, refObject, jnienv_to_javavm(env), proxy_cleanup); //DeathRecipientList保存了一個用于死亡通知的list sp<DeathRecipientList> drl = new DeathRecipientList; drl->incStrong((void*)javaObjectForIBinder); //將死亡通知list和BinderProxy對象聯系起來 env->SetIntField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jint>(drl.get())); // 增加該Proxy對象的引用計數 android_atomic_inc(&gNumProxyRefs); /*下面這個函數用于垃圾回收。創建的Proxy對象一旦超過200個,該函數 將調用BinderInter類的ForceGc做一次垃圾回收 */ incRefsCreated(env); } returnobject; } ``` BinderInternal.getContextObject的代碼有點多,簡單整理一下,可知該函數完成了以下兩個工作: - 創建了一個Java層的BinderProxy對象。 - 通過JNI,該BinderProxy對象和一個Native的BpProxy對象掛鉤,而該BpProxy對象的通信目標就是ServiceManager。 接下來討論asInterface()方法,大家還記得在Native層Binder中那個著名的interface\_cast宏嗎?在Java層中,雖然沒有這樣的宏,但是定義了一個類似的函數asInterface。下面來分析ServiceManagerNative類的asInterface函數,其代碼如下: **ServiceManagerNative.java-->ServiceManagerNative.asInterface()** ``` static public IServiceManager asInterface(IBinderobj) { ......// 以obj為參數,創建一個ServiceManagerProxy對象 returnnew ServiceManagerProxy(obj); } ``` 上面代碼和Native層interface\_cast非常類似,都是以一個BpProxy對象為參數構造一個和業務相關的Proxy對象,例如這里的ServiceManagerProxy對象。ServiceManagerProxy對象的各個業務函數會將相應請求打包后交給BpProxy對象,最終由BpProxy對象發送給Binder驅動以完成一次通信。 **說明** 實際上BpProxy也不會直接和Binder驅動交互,真正和Binder驅動交互的是IPCThreadState。 ##### (2)addService函數分析 現在來分析ServiceManagerProxy的addService函數,其代碼如下: **ServcieManagerNative.java-->ServiceManagerProxy.addService()** ``` public void addService(String name, IBinderservice) throwsRemoteException { Parceldata = Parcel.obtain(); Parcelreply = Parcel.obtain(); data.writeInterfaceToken(IServiceManager.descriptor); data.writeString(name); // 注意下面這個writeStrongBinder函數,后面我們會詳細分析它 data.writeStrongBinder(service); /*mRemote實際上就是BinderProxy對象,調用它的transact,將封裝好的請求數據 發送出去 * mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0); reply.recycle(); data.recycle(); } ``` BinderProxy的transact,是一個native函數,其實現函數的代碼如下所示: **android_util_Binder.cpp-->android_os_BinderProxy_transact()** ``` static jbooleanandroid_os_BinderProxy_transact(JNIEnv* env, jobject obj, jint code, jobject dataObj, jobject replyObj, jint flags) { ...... // 從Java的Parcel對象中得到作為參數的Native的Parcel對象 Parcel*data = parcelForJavaObject(env, dataObj); if (data== NULL) { return JNI_FALSE; } // 得到一個用于接收回復的Parcel對象 Parcel*reply = parcelForJavaObject(env, replyObj); if(reply == NULL && replyObj != NULL) { return JNI_FALSE; } // 從Java的BinderProxy對象中得到之前已經創建好的那個Native的BpBinder對象 IBinder*target = (IBinder*) env->GetIntField(obj, gBinderProxyOffsets.mObject); ...... // 通過Native的BpBinder對象,將請求發送給ServiceManager status_terr = target->transact(code, *data, reply, flags); ...... signalExceptionForError(env,obj, err); returnJNI_FALSE; } ``` 看了上面的代碼會發現,Java層的Binder最終還是要借助Native的Binder進行通信的。 * * * * * **說明** 從架構的角度看,在Java中搭建了一整套框架,如IBinder接口,Binder類和BinderProxy類。但是從通信角度看,不論架構的編寫采用的是Native語言還是Java語言,只要把請求傳遞到Binder驅動就可以了,所以通信的目的是向binder發送請求和接收回復。在這個目的之上,考慮到軟件的靈活性和可擴展性,于是編寫了一個架構。反過來說,也可以不使用架構(即沒有使用任何接口、派生之類的東西)而直接和binder交互,例如ServiceManager作為Binder的一個核心程序,就是直接讀取/dev/binder設備,獲取并處理請求。從這一點上看,Binder的目的雖是簡單的(即打開binder設備,然后讀請求和寫回復),但是架構是復雜的(編寫各種接口類和封裝類等)。我們在研究源碼時,一定要先搞清楚目的。實現只不過是達到該目的的一種手段和方式。脫離目的的實現,如緣木求魚,很容易偏離事物本質。 * * * * * 在對addService進行分析時曾提示writeStrongBinder是一個特別的函數。那么它特別在哪里呢?下面將給出解釋。 ##### (3)三人行之Binder、JavaBBinderHolder和JavaBBinder ActivityManagerService從ActivityManagerNative類派生,并實現了一些接口,其中和Binder的相關的只有這個ActivityManagerNative類,其原型如下: **ActivityManagerNative.java-->ActivityManagerNative** ``` public abstract class ActivityManagerNative extends Binder implementsIActivityManager ``` ActivityManagerNative從Binder派生,并實現了IActivityManager接口。下面來看ActivityManagerNative的構造函數: **ActivityManagerNative.java-->ActivityManagerNative.ActivityManagerNative()** ``` public ActivityManagerNative() { attachInterface(this, descriptor);// 該函數很簡單,讀者可自行分析 } ``` 而ActivityManagerNative父類的構造函數則是Binder的構造函數: **Binder.java-->Binder.Binder()** ``` public Binder() { init(); } ``` Binder構造函數中會調用native的init函數,其實現的代碼如下: **android_util_Binder.cpp-->android_os_Binder_init()** ``` static void android_os_Binder_init(JNIEnv* env,jobject obj) { // 創建一個JavaBBinderHolder對象 JavaBBinderHolder* jbh = new JavaBBinderHolder(); bh->incStrong((void*)android_os_Binder_init); // 將這個JavaBBinderHolder對象保存到Java Binder對象的mObject成員中 env->SetIntField(obj, gBinderOffsets.mObject, (int)jbh); } ``` 從上面代碼可知,Java的Binder對象將和一個Native的JavaBBinderHolder對象相關聯。那么,JavaBBinderHolder是何方神圣呢?其定義如下: **android_util_Binder.cpp-->JavaBBinderHolder** ``` class JavaBBinderHolder : public RefBase { public: sp<JavaBBinder> get(JNIEnv* env, jobject obj) { AutoMutex _l(mLock); sp<JavaBBinder> b = mBinder.promote(); if(b == NULL) { // 創建一個JavaBBinder,obj實際上是Java層中的Binder對象 b = new JavaBBinder(env, obj); mBinder = b; } return b; } ...... private: Mutex mLock; wp<JavaBBinder> mBinder; }; ``` 從派生關系上可以發現,JavaBBinderHolder僅從RefBase派生,所以它不屬于Binder家族。Java層的Binder對象為什么會和Native層的一個與Binder家族無關的對象綁定呢?仔細觀察JavaBBinderHolder的定義可知:JavaBBinderHolder類的get函數中創建了一個JavaBBinder對象,這個對象就是從BnBinder派生的。 那么,這個get函數是在哪里調用的?答案在下面這句代碼中: ``` //其中,data是Parcel對象,service此時還是ActivityManagerService data.writeStrongBinder(service); ``` writeStrongBinder會做一個替換工作,下面是它的native代碼實現: **android_util_Binder.cpp-->android_os_Parcel_writeStrongBinder()** ``` static voidandroid_os_Parcel_writeStrongBinder(JNIEnv* env, jobject clazz, jobject object) { /*parcel是一個Native的對象,writeStrongBinder的真正參數是 ibinderForJavaObject()的返回值*/ conststatus_t err = parcel->writeStrongBinder( ibinderForJavaObject(env, object)); } [android_util_Binder.cpp-->ibinderForJavaObject()] sp<IBinder> ibinderForJavaObject(JNIEnv*env, jobject obj) { /* 如果Java的obj是Binder類,則首先獲得JavaBBinderHolder對象,然后調用 它的get()函數。而這個get將返回一個JavaBBinder */ if(env->IsInstanceOf(obj, gBinderOffsets.mClass)) { JavaBBinderHolder* jbh = (JavaBBinderHolder*)env->GetIntField(obj, gBinderOffsets.mObject); return jbh != NULL ? jbh->get(env, obj) : NULL; } // 如果obj是BinderProxy類,則返回Native的BpBinder對象 if(env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) { return (IBinder*) env->GetIntField(obj, gBinderProxyOffsets.mObject); } returnNULL; } ``` 根據上面的介紹會發現,addService實際添加到Parcel的并不是AMS本身,而是一個叫JavaBBinder的對象。正是將它最終傳遞到Binder驅動。 讀者此時容易想到,Java層中所有的Binder對應的都是這個JavaBBinder。當然,不同的Binder對象對應不同的JavaBBinder對象。 圖2-2展示了Java Binder、JavaBBinderHolder和JavaBBinder的關系。 :-: ![](http://img.blog.csdn.net/20150806154325282?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center) 圖 2 - 2 Java Binder 、JavaBBinderHolder和JavaBBinder三者的關系 從圖2-2可知: - Java層的Binder通過mObject指向一個Native層的JavaBBInderHolder對象。 - Native層的JavaBBinderHolder對象通過mBinder成員變量指向一個Native的JavaBBinder對象。 - Native的JavaBBinder對象又通過mObject變量指向一個Java層的Binder對象。 為什么不直接讓Java層的Binder對象指向Native層的JavaBBinder對象呢?由于缺乏設計文檔,這里不便妄加揣測,但從JavaBBinderHolder的實現上來分析,估計和垃圾回收(內存管理)有關,因為JavaBBinderHolder中的mBinder對象的類型被定義成弱引用wp了。 >[info] **建議** 對此有更好的解釋的讀者,不妨與大家分享一下。 #### 2. ActivityManagerService響應請求 初見JavaBBinde時,多少有些吃驚。回想一下Native層的Binder架構:雖然在代碼中調用的是Binder類提供的接口,但其對象卻是一個實際的服務端對象,例如MediaPlayerService對象,AudioFlinger對象。 而在Java層的Binder架構中,JavaBBinder卻是一個和業務完全無關的對象。那么,這個對象如何實現不同業務呢? 為回答此問題,我們必須看它的onTransact函數。當收到請求時,系統會調用這個函數。 說明 關于這個問題,建議讀者閱讀卷I第6章“深入理解Binder”。 **android_util_Binder.cpp-->JavaBBinder::onTransact()** ``` virtual status_t onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags =0) { JNIEnv*env = javavm_to_jnienv(mVM); IPCThreadState* thread_state = IPCThreadState::self(); ....... // 調用Java層Binder對象的execTranscat函數 jbooleanres = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,code, (int32_t)&data, (int32_t)reply, flags); ...... returnres != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION; } ``` 就本例而言,上面代碼中的mObject就是ActivityManagerService,現在調用它的execTransact()方法,該方法在Binder類中實現,具體代碼如下: **Binder.java-->Binder.execTransact()** ``` private boolean execTransact(int code, intdataObj, int replyObj,int flags) { Parceldata = Parcel.obtain(dataObj); Parcelreply = Parcel.obtain(replyObj); booleanres; try { //調用onTransact函數,派生類可以重新實現這個函數,以完成業務功能 res= onTransact(code, data, reply, flags); } catch{ ... } reply.recycle(); data.recycle(); returnres; } ``` ActivityManagerNative類實現了onTransact函數,代碼如下: **ActivityManagerNative.java-->ActivityManagerNative.onTransact()** ``` public boolean onTransact(int code, Parcel data,Parcel reply, int flags) throws RemoteException { switch(code) { caseSTART_ACTIVITY_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder b = data.readStrongBinder(); ...... //再由ActivityManagerService實現業務函數startActivity intresult = startActivity(app, intent, resolvedType, grantedUriPermissions, grantedMode, resultTo, resultWho, requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler); reply.writeNoException(); reply.writeInt(result); return true; } .... // 處理其他請求的case } } ``` 由此可以看出,JavaBBinder僅是一個傳聲筒,它本身不實現任何業務函數,其工作是: - 當它收到請求時,只是簡單地調用它所綁定的Java層Binder對象的exeTransact。 - 該Binder對象的exeTransact調用其子類實現的onTransact函數。 - 子類的onTransact函數將業務又派發給其子類來完成。請讀者務必注意其中的多層繼承關系。 通過這種方式,來自客戶端的請求就能傳遞到正確的Java Binder對象了。圖2-3展示AMS響應請求的整個流程。 :-: ![](http://img.blog.csdn.net/20150806154338652?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center) 圖 2 - 3 AMS響應請求的流程 在圖2-3中,右上角的大方框表示AMS這個對象,其間的虛線箭頭表示調用子類重載的函數。
                  <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>

                              哎呀哎呀视频在线观看