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

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                這個例子源自ActivityManagerService,我們試圖通過它揭示Java層Binder的工作原理。先來描述一下該例子的分析步驟: - 首先分析AMS如何將自己注冊到ServiceManager。 - 然后分析AMS如何響應客戶端的Binder調用請求。 本例的起點是setSystemProcess,其代碼如下所示: **ActivityManagerService.java** ~~~ public static void setSystemProcess() { try { ActivityManagerService m = mSelf; //將ActivityManagerService服務注冊到ServiceManager中 ServiceManager.addService("activity", m);...... } ...... return; } ~~~ 上面所示代碼行的目的是將ActivityManagerService服務加到ServiceManager中。ActivityManagerService(以后簡稱AMS)是Android核心服務中的核心,我們以后會經常和它打交道。 大家知道,整個Android系統中有一個Native的ServiceManager(以后簡稱SM)進程,它統籌管理Android系統上的所有Service。成為一個Service的首要條件是先在SM中注冊。下面來看Java層的Service是如何向SM注冊的。 1. 向ServiceManager注冊服務 (1) 創建ServiceManagerProxy 向SM注冊服務的函數叫addService,其代碼如下: **ServiceManager.java** ~~~ public static void addService(String name, IBinderservice) { try { //getIServiceManager返回什么 getIServiceManager().addService(name,service); } ...... } //分析getIServiceManager函數 private static IServiceManagergetIServiceManager() { ...... //調用asInterface,傳遞的參數類型為IBinder sServiceManager= ServiceManagerNative.asInterface( BinderInternal.getContextObject()); returnsServiceManager; } ~~~ asInterface的參數為BinderInternal.getContextObject的返回值。這是一個native的函數,其實現的代碼為: **android_util_Binder.cpp** ~~~ 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); } ~~~ **android_util_Binder.cpp** ~~~ 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 */ jobject object =(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) { 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。 大家還記得在Native層Binder中那個著名的interface_cast宏嗎?在Java層中,雖然沒有這樣的宏,但是定義了一個類似的函數asInterface。下面來分析ServiceManagerNative類的asInterface函數,其代碼如下: **ServiceManagerNative.java** ~~~ static public IServiceManager asInterface(IBinderobj) { ...... //以obj為參數,創建一個ServiceManagerProxy對象 return new ServiceManagerProxy(obj); } ~~~ 上面代碼和Native層interface_cast非常類似,都是以一個BpProxy對象為參數構造一個和業務相關的Proxy對象,例如這里的ServiceManagerProxy對象。ServiceManagerProxy對象的各個業務函數會將相應請求打包后交給BpProxy對象,最終由BpProxy對象發送給Binder驅動以完成一次通信。 >[info] **提示 **實際上BpProxy也不會和Binder驅動交互,真正和Binder驅動交互的是IPCThreadState。 (2) addService函數分析 現在來分析ServiceManagerProxy的addService函數,其代碼如下: **ServcieManagerNative.java** ~~~ public void addService(String name, IBinderservice) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = 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** ~~~ static jbooleanandroid_os_BinderProxy_transact(JNIEnv* env, jobject obj, jintcode, 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進行通信的。 關于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** ~~~ public abstract class ActivityManagerNative extends Binder implementsIActivityManager ~~~ ActivityManagerNative從Binder派生,并實現了IActivityManager接口。下面來看ActivityManagerNative的構造函數: **ActivityManagerNative.java** ~~~ public ActivityManagerNative() { attachInterface(this, descriptor);//該函數很簡單,讀者可自行分析 } //這是ActivityManagerNative父類的構造函數,即Binder的構造函數 public Binder() { init(); } ~~~ Binder構造函數中會調用native的init函數,其實現的代碼如下: **android_util_Binder.cpp** ~~~ 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** ~~~ 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** ~~~ static void android_os_Parcel_writeStrongBinder(JNIEnv*env, jobjectclazz, jobject object) { //parcel是一個Native的對象,writeStrongBinder的真正參數是 //ibinderForJavaObject的返回值 conststatus_t err = parcel->writeStrongBinder( ibinderForJavaObject(env,object)); } ~~~ **android_util_Binder.cpp** ~~~ 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/20150803102559447?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center) 圖2-2 JavaBinder、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了。 * * * * * **建議** 對此,如果讀者有更好的解釋,不妨與大家分享一下。 * * * * * 2. ActivityManagerService響應請求 初見JavaBBinde時,多少有些吃驚。回想一下Native層的Binder架構:雖然在代碼中調用的是Binder類提供的接口,但其對象卻是一個實際的服務端對象,例如MediaPlayerService對象,AudioFlinger對象。 而Java層的Binder架構中,JavaBBinder卻是一個和業務完全無關的對象。那么,這個對象如何實現不同業務呢? 為回答此問題,我們必須看它的onTransact函數。當收到請求時,系統會調用這個函數。 關于這個問題,建議讀者閱讀卷I第六章《深入理解Binder》。 **android_util_Binder.cpp** ~~~ 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函數 jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,code, (int32_t)&data,(int32_t)reply, flags); ...... return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION; } ~~~ 就本例而言,上面代碼中的mObject就是ActivityManagerService,現在調用它的execTransact函數,該函數在Binder類中實現,具體代碼如下: **Binder.java** ~~~ private boolean execTransact(int code, intdataObj, int replyObj,int flags) { Parcel data = Parcel.obtain(dataObj); Parcel reply = Parcel.obtain(replyObj); boolean res; try{ //調用onTransact函數,派生類可以重新實現這個函數,以完成業務功能 res = onTransact(code, data, reply, flags); }...... reply.recycle(); data.recycle(); return res; } } ~~~ ActivityManagerNative類實現了onTransact函數,代碼如下: **ActivityManagerNative.java** ~~~ 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; } ~~~ 由此可以看出,JavaBBinder僅是一個傳聲筒,它本身不實現任何業務函數,其工作是: - 當它收到請求時,只是簡單地調用它所綁定的Java層Binder對象的exeTransact。 - 該Binder對象的exeTransact調用其子類實現的onTransact函數。 - 子類的onTransact函數將業務又派發給其子類來完成。請讀者務必注意其中的多層繼承關系。 通過這種方式,來自客戶端的請求就能傳遞到正確的Java Binder對象了。圖2-3展示AMS響應請求的整個流程。 :-: ![](http://img.blog.csdn.net/20150803102725141?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>

                              哎呀哎呀视频在线观看