日本三级床上影片高清

  • <tr id='CgwhnW'><strong id='CgwhnW'></strong><small id='CgwhnW'></small><button id='CgwhnW'></button><li id='CgwhnW'><noscript id='CgwhnW'><big id='CgwhnW'></big><dt id='CgwhnW'></dt></noscript></li></tr><ol id='CgwhnW'><option id='CgwhnW'><table id='CgwhnW'><blockquote id='CgwhnW'><tbody id='CgwhnW'></tbody></blockquote></table></option></ol><u id='CgwhnW'></u><kbd id='CgwhnW'><kbd id='CgwhnW'></kbd></kbd>

    <code id='CgwhnW'><strong id='CgwhnW'></strong></code>

    <fieldset id='CgwhnW'></fieldset>
          <span id='CgwhnW'></span>

              <ins id='CgwhnW'></ins>
              <acronym id='CgwhnW'><em id='CgwhnW'></em><td id='CgwhnW'><div id='CgwhnW'></div></td></acronym><address id='CgwhnW'><big id='CgwhnW'><big id='CgwhnW'></big><legend id='CgwhnW'></legend></big></address>

              <i id='CgwhnW'><div id='CgwhnW'><ins id='CgwhnW'></ins></div></i>
              <i id='CgwhnW'></i>
            1. <dl id='CgwhnW'></dl>
              1. <blockquote id='CgwhnW'><q id='CgwhnW'><noscript id='CgwhnW'></noscript><dt id='CgwhnW'></dt></q></blockquote><noframes id='CgwhnW'><i id='CgwhnW'></i>

                Binder Android Java接口

                Binder機制學習總結之Java接口部分

                2019-04-17
                39次瀏覽

                ? ? ? ? 因為上一節service manager中,對於binder通信的⊙客戶端(BpServiceManager)和服務端(service manager進程)已經有比較詳細的解釋,所以,不再對於Binder通信的client端和server端做分析,有興趣的同學可以看看MediaPlayerService和MediaPlayer,網上很多⊙資料有講解。

                ? ? ? ? 當目〒前為止,所有的代碼都是以C/C++語言的,但是,App開☆發者通常使用Java語言,那麽Java是如何使用Binder通信的呢?

                AIDL ? ? ? ? 很多時候,我們是通過aidl(Android Interface Define Language)間接的使用Binder機制的。例如,我們準備了下面這樣一個aidl文件:

                package?com.ray.example;
                
                interface?RInterface?{
                ????void?hello(String?message);
                }

                ? ? ? ?經過IDE的編譯,我們會得到下面這樣的Java文件:

                /*___Generated_by_IDEA___*/
                
                /*
                ?*?This?file?is?auto-generated.??DO?NOT?MODIFY.
                ?*?Original?file:?/home/ray/Learning&Study/BinderProProject/SearchApp/src/main/java/com/ray/example/RInterface.aidl
                ?*/
                package?com.ray.example;
                public?interface?RInterface?extends?android.os.IInterface
                {
                /**?Local-side?IPC?implementation?stub?class.?*/
                public?static?abstract?class?Stub?extends?android.os.Binder?implements?com.ray.example.RInterface
                {
                private?static?final?java.lang.String?DESCRIPTOR?=?"com.ray.example.RInterface";
                /**?Construct?the?stub?at?attach?it?to?the?interface.?*/
                public?Stub()
                {
                this.attachInterface(this,?DESCRIPTOR);
                }
                /**
                ?*?Cast?an?IBinder?object?into?an?com.ray.example.RInterface?interface,
                ?*?generating?a?proxy?if?needed.
                ?*/
                public?static?com.ray.example.RInterface?asInterface(android.os.IBinder?obj)
                {
                if?((obj==null))?{
                return?null;
                }
                android.os.IInterface?iin?=?obj.queryLocalInterface(DESCRIPTOR);
                if?(((iin!=null)&&(iin?instanceof?com.ray.example.RInterface)))?{
                return?((com.ray.example.RInterface)iin);
                }
                return?new?com.ray.example.RInterface.Stub.Proxy(obj);
                }
                @Override?public?android.os.IBinder?asBinder()
                {
                return?this;
                }
                @Override?public?boolean?onTransact(int?code,?android.os.Parcel?data,?android.os.Parcel?reply,?int?flags)?throws?android.os.RemoteException
                {
                switch?(code)
                {
                case?INTERFACE_TRANSACTION:
                {
                reply.writeString(DESCRIPTOR);
                return?true;
                }
                case?TRANSACTION_hello:
                {
                data.enforceInterface(DESCRIPTOR);
                java.lang.String?_arg0;
                _arg0?=?data.readString();
                this.hello(_arg0);
                reply.writeNoException();
                return?true;
                }
                }
                return?super.onTransact(code,?data,?reply,?flags);
                }
                private?static?class?Proxy?implements?com.ray.example.RInterface
                {
                private?android.os.IBinder?mRemote;
                Proxy(android.os.IBinder?remote)
                {
                mRemote?=?remote;
                }
                @Override?public?android.os.IBinder?asBinder()
                {
                return?mRemote;
                }
                public?java.lang.String?getInterfaceDescriptor()
                {
                return?DESCRIPTOR;
                }
                @Override?public?void?hello(java.lang.String?message)?throws?android.os.RemoteException
                {
                android.os.Parcel?_data?=?android.os.Parcel.obtain();
                android.os.Parcel?_reply?=?android.os.Parcel.obtain();
                try?{
                _data.writeInterfaceToken(DESCRIPTOR);
                _data.writeString(message);
                mRemote.transact(Stub.TRANSACTION_hello,?_data,?_reply,?0);
                _reply.readException();
                }
                finally?{
                _reply.recycle();
                _data.recycle();
                }
                }
                }
                static?final?int?TRANSACTION_hello?=?(android.os.IBinder.FIRST_CALL_TRANSACTION?+?0);
                }
                public?void?hello(java.lang.String?message)?throws?android.os.RemoteException;
                }

                ? ? ? ? 編譯產生的java文件提供了三↘個對象:

                RInterface接口:繼承自IInterface接口,並且有一個hello的成〇員函數。作為server和client之間▲的約定,雙方都不管什麽身份會使用。

                RInterface.Stub抽象類:繼承自Binder類,並且提供了ㄨonTransact函數的實ξ現,以及靜態函數asInterface。

                RInterface.Stub.Proxy類:實現了RInterface接口,實現了hello函數。

                XXXX.Stub ? ? ? ??主要由Server端實現,Server端通過繼承本類,來提供具體的處理邏ξ輯。通常,在Server端,我們會有如下代碼:

                package?com.ray.example;
                
                import?android.app.Service;
                import?android.content.Intent;
                import?android.os.IBinder;
                import?android.os.RemoteException;
                import?android.util.Log;
                
                /**
                ?*?Created?by?ray?on?2/7/14.
                ?*/
                public?class?RServer?extends?RInterface.Stub?{
                
                ????public?final?String?TAG_RAY?=?"ray";
                
                ????@Override
                ????public?void?hello(String?message)?throws?RemoteException?{
                ????????Log.i(TAG_RAY,"Hello~?"?+?message);
                ????}
                }

                ? ? ? ? 這龍神之鎧上面裏通過重載來hello函數來提供具體的處理邏ξ輯。而hello函數是如何被調用的呢?這就需要回顧RInterface.Stub類對於onTransact函數的重載:

                @Override?public?boolean?onTransact(int?code,?android.os.Parcel?data,?android.os.Parcel?reply,?int?flags)?throws?android.os.RemoteException
                {
                switch?(code)
                {
                case?INTERFACE_TRANSACTION:
                {
                reply.writeString(DESCRIPTOR);
                return?true;
                }
                case?TRANSACTION_hello:
                {
                data.enforceInterface(DESCRIPTOR);
                java.lang.String?_arg0;
                _arg0?=?data.readString();
                this.hello(_arg0);
                reply.writeNoException();
                return?true;
                }
                }
                return?super.onTransact(code,?data,?reply,?flags);
                }

                ? ? ? ? 當onTransact函數被以特定的參數調用時,hello函數會被所有人調用:

                static?final?int?TRANSACTION_hello?=?(android.os.IBinder.FIRST_CALL_TRANSACTION?+?0);

                ? ? ? ? Android系統約定,code必須大於等於

                ????int?FIRST_CALL_TRANSACTION??=?0x00000001;

                ? ? ? ? 並且,小於等於

                ????int?LAST_CALL_TRANSACTION???=?0x00ffffff;

                ? ? ? ? 否則,code可能和Binder協議的一些保留code沖突。 ? ? ? ? 至於onTransact函數是如何被調用,就需要涉及》到Binder類的內部實現,我們稍ㄨ後分析。 XXXX.Stub.Proxy ? ? ? ? 主要由Client端使用,顧名思義,擔當Server的代理角色。 ? ? ? ? 通常,在Clent端,會有類似如下的代▅碼:

                package?com.ray.example;
                
                import?android.os.IBinder;
                import?android.os.RemoteException;
                
                /**
                ?*?Created?by?ray?on?2/7/14.
                ?*/
                public?class?RClient?{
                
                ????private?RInterface?mRInterface;
                
                ????public?RClient?(IBinder?binder){
                ????????mRInterface?=?RInterface.Stub.asInterface(binder);
                ????}
                
                ????public?void?sayHello(String?message)?throws?RemoteException?{
                ????????mRInterface.hello("Ray");
                ????}
                }

                ? ? ? ? 而,我們知道Rinterface.Stub.asInterface函數會構造一個RInterface.Stub.Proxy類的實例,並返回:

                public?static?com.ray.example.RInterface?asInterface(android.os.IBinder?obj)
                {
                if?((obj==null))?{
                return?null;
                }
                android.os.IInterface?iin?=?obj.queryLocalInterface(DESCRIPTOR);
                if?(((iin!=null)&&(iin?instanceof?com.ray.example.RInterface)))?{
                return?((com.ray.example.RInterface)iin);
                }
                return?new?com.ray.example.RInterface.Stub.Proxy(obj);
                }

                ? ? ? ? 所以,客戶端的mRInterface實際上是RInterface.Stub.Proxy。而調用Proxy對於hello的實現:

                @Override?public?void?hello(java.lang.String?message)?throws?android.os.RemoteException
                {
                android.os.Parcel?_data?=?android.os.Parcel.obtain();
                android.os.Parcel?_reply?=?android.os.Parcel.obtain();
                try?{
                _data.writeInterfaceToken(DESCRIPTOR);
                _data.writeString(message);
                mRemote.transact(Stub.TRANSACTION_hello,?_data,?_reply,?0);//mRemote的類型為IBinder
                _reply.readException();
                }
                finally?{
                _reply.recycle();
                _data.recycle();
                }

                ? ? ? ?很明顯的,是通過Binder機制♂轉發請求,但是mRemote是如何實現transaction函數的呢?我們暫時還不知∞道。 小結 aidl文件編只有輪流休息譯成java文件時,提供了三個對象:XXXX接口,這個接嘖嘖口根據aidl文件的內容生成,作為通信雙方的約定。XXXX.Stub抽象類,這個抽象Ψ類繼承自Binder類。它實現了從Binder中讀取到數據以後,呼叫業務邏輯處理代碼的功能。Server端通過繼承並實現業務邏輯來使用它。XXXX.Stub.Proxy類,這個類封裝了一個IBinder接口,它實現了廢物把Client端請求通過Binder發送到Server端的功能。Client可以通過XXXX.Stub.asInterface函數來獲一旁得XXXX.Stub.Proxy實例。 IBinder接口 ? ? ? ? IBinder接口的█聲明,並不難理解:

                public?interface?IBinder?{
                
                ????int?FIRST_CALL_TRANSACTION??=?0x00000001;
                
                ????int?LAST_CALL_TRANSACTION???=?0x00ffffff;
                ????
                ????//異步binder
                ????int?FLAG_ONEWAY?????????????=?0x00000001;
                ????
                ????public?String?getInterfaceDescriptor()?throws?RemoteException;
                ????
                ????public?boolean?pingBinder();
                ????
                ????public?boolean?isBinderAlive();
                ????
                ????public?IInterface?queryLocalInterface(String?descriptor);
                ????
                ????public?void?dump(FileDescriptor?fd,?String[]?args)?throws?RemoteException;
                ????
                ????public?void?dumpAsync(FileDescriptor?fd,?String[]?args)?throws?RemoteException;
                ????//進行binder通信
                ????public?boolean?transact(int?code,?Parcel?data,?Parcel?reply,?int?flags)
                ????????throws?RemoteException;
                ????//死亡通知
                ????public?interface?DeathRecipient?{
                ????????public?void?binderDied();
                ????}
                ????//註冊死亡通知
                ????public?void?linkToDeath(DeathRecipient?recipient,?int?flags)
                ????????????throws?RemoteException;
                ????//註銷死↓亡通知
                ????public?boolean?unlinkToDeath(DeathRecipient?recipient,?int?flags);
                }

                Binder類 ? ? ? ? ? ? ? ? Binder類的聲ω明有點長,所以,這邊僅僅列出幾個重點函數:

                public?class?Binder?implements?IBinder?{
                ????/*?mObject?is?used?by?native?code,?do?not?remove?or?rename?*/
                ????private?int?mObject;
                ????private?IInterface?mOwner;
                ????private?String?mDescriptor;
                
                ????//?client端的進程id
                ????public?static?final?native?int?getCallingPid();
                ????//?client端的用戶id
                ????public?static?final?native?int?getCallingUid();????
                ????//?清除client端的進程id和用戶id
                ????public?static?final?native?long?clearCallingIdentity();
                
                ????public?Binder()?{
                ????????init();????
                ????}
                
                ????/**
                ?????*?Default?implementation?is?a?stub?that?returns?false.??You?will?want
                ?????*?to?override?this?to?do?the?appropriate?unmarshalling?of?transactions.
                ?????*
                ?????*?If?you?want?to?call?this,?call?transact().

                */ ? ?protected boolean onTransact(int code, Parcel data, Parcel reply, ? ? ? ? ? ?int flags) throws RemoteException { ? ? ? ?if (code == INTERFACE_TRANSACTION) { ? ? ? ? ? ?reply.writeString(getInterfaceDescriptor()); ? ? ? ? ? ?return true; ? ? ? ?} else if (code == DUMP_TRANSACTION) { ? ? ? ? ? ?ParcelFileDescriptor fd = data.readFileDescriptor(); ? ? ? ? ? ?String[] args = data.readStringArray(); ? ? ? ? ? ?if (fd != null) { ? ? ? ? ? ? ? ?try { ? ? ? ? ? ? ? ? ? ?dump(fd.getFileDescriptor(), args); ? ? ? ? ? ? ? ?} finally { ? ? ? ? ? ? ? ? ? ?try { ? ? ? ? ? ? ? ? ? ? ? ?fd.close(); ? ? ? ? ? ? ? ? ? ?} catch (IOException e) { ? ? ? ? ? ? ? ? ? ? ? ?// swallowed, not propagated back to the caller ? ? ? ? ? ? ? ? ? ?} ? ? ? ? ? ? ? ?} ? ? ? ? ? ?} ? ? ? ? ? ?// Write the StrictMode header. ? ? ? ? ? ?if (reply != null) { ? ? ? ? ? ? ? ?reply.writeNoException(); ? ? ? ? ? ?} else { ? ? ? ? ? ? ? ?StrictMode.clearGatheredViolations(); ? ? ? ? ? ?} ? ? ? ? ? ?return true; ? ? ? ?} ? ? ? ?return false; ? ?} ? ?/** ? ? * Default implementation rewinds the parcels and calls onTransact. ?On ? ? * the remote side, transact calls into the binder to do the IPC. ? ? */ ? ?public final boolean transact(int code, Parcel data, Parcel reply, ? ? ? ? ? ?int flags) throws RemoteException { ? ? ? ?if (false) Log.v("Binder", "Transact: " + code + " to " + this); ? ? ? ?if (data != null) { ? ? ? ? ? ?data.setDataPosition(0); ? ? ? ?} ? ? ? ?boolean r = onTransact(code, data, reply, flags); ? ? ? ?if (reply != null) { ? ? ? ? ? ?reply.setDataPosition(0); ? ? ? ?} ? ? ? ?return r; ? ?} ? ?protected void finalize() throws Throwable { ? ? ? ?try { ? ? ? ? ? ?destroy(); ? ? ? ?} finally { ? ? ? ? ? ?super.finalize(); ? ? ? ?} ? ?} ? ? ? ?private native final void init(); ? ?private native final void destroy(); ? ?// Entry point from android_util_Binder.cpp's onTransact ? ?private boolean execTransact(int code, int dataObj, int replyObj, ? ? ? ? ? ?int flags) { ? ? ? ?Parcel data = Parcel.obtain(dataObj); ? ? ? ?Parcel reply = Parcel.obtain(replyObj); ? ? ? ?// theoretically, we should call transact, which will call onTransact, ? ? ? ?// but all that does is rewind it, and we just got these from an IPC, ? ? ? ?// so we'll just call it directly. ? ? ? ?boolean res; ? ? ? ?try { ? ? ? ? ? ?res = onTransact(code, data, reply, flags); ? ? ? ?} catch (RemoteException e) { ? ? ? ? ? ?reply.setDataPosition(0); ? ? ? ? ? ?reply.writeException(e); ? ? ? ? ? ?res = true; ? ? ? ?} catch (RuntimeException e) { ? ? ? ? ? ?reply.setDataPosition(0); ? ? ? ? ? ?reply.writeException(e); ? ? ? ? ? ?res = true; ? ? ? ?} catch (OutOfMemoryError e) { ? ? ? ? ? ?RuntimeException re = new RuntimeException("Out of memory", e); ? ? ? ? ? ?reply.setDataPosition(0); ? ? ? ? ? ?reply.writeException(re); ? ? ? ? ? ?res = true; ? ? ? ?} ? ? ? ?reply.recycle(); ? ? ? ?data.recycle(); ? ? ? ?return res; ? ?}

                ? ? ? ? 到目前為止,我們似№乎還沒發現Java的Binder類和native層的C++Binder接口存在什麽聯系,不過,我們還沒看過Binder類的原生方法。 android_os_Binder_init

                static?void?android_os_Binder_init(JNIEnv*?env,?jobject?obj)
                {
                ????JavaBBinderHolder*?jbh?=?new?JavaBBinderHolder();
                ????if?(jbh?==?NULL)?{
                ????????jniThrowException(env,?"java/lang/OutOfMemoryError",?NULL);
                ????????return;
                ????}
                ????ALOGV("Java?Binder?%p:?acquiring?first?ref?on?holder?%p",?obj,?jbh);
                ????jbh->incStrong((void*)android_os_Binder_init);
                ????env->SetIntField(obj,?gBinderOffsets.mObject,?(int)jbh);
                }

                ? ? ? ? init函可惜數構造了一個※JavaBBinderHolder實例,看起來奧秘應該就在這個JavaBBinderHolder中了。不過,在此之前,我們先解↑釋下

                ????env->SetIntField(obj,?gBinderOffsets.mObject,?(int)jbh);

                ? ? ? ?首先,需要從gBinderoffsets變量說起:

                static?struct?bindernative_offsets_t
                {
                ????//?Class?state.
                ????jclass?mClass;
                ????jmethodID?mExecTransact;
                
                ????//?Object?state.
                ????jfieldID?mObject;
                
                }?gBinderOffsets;

                ? ? ? ? 它有三個砸到了死神之左眼之上成員。而這三▓個成員的含義,我們可以從下面的代碼中了解:

                const?char*?const?kBinderPathName?=?"android/os/Binder"
                
                static?int?int_register_android_os_Binder(JNIEnv*?env)
                {
                ????jclass?clazz;
                
                ????clazz?=?env->FindClass(kBinderPathName);//clazz即Java?Binder類
                ????LOG_FATAL_IF(clazz?==?NULL,?"Unable?to?find?class?android.os.Binder");
                
                ????gBinderOffsets.mClass?=?(jclass)?env->NewGlobalRef(clazz);
                ????gBinderOffsets.mExecTransact
                ????????=?env->GetMethodID(clazz,?"execTransact",?"(IIII)Z");//mExecTransact指向Binder類的execTrasaction函數
                ????assert(gBinderOffsets.mExecTransact);
                
                ????gBinderOffsets.mObject
                ????????=?env->GetFieldID(clazz,?"mObject",?"I");//mObject指向Binder類的mObject成員
                ????assert(gBinderOffsets.mObject);
                
                ????return?AndroidRuntime::registerNativeMethods(//註冊原生」函數
                ????????env,?kBinderPathName,
                ????????gBinderMethods,?NELEM(gBinderMethods));
                }

                ? ? ? ? 而register_android_os_Binder函數則會在Dalvik虛擬機啟動的時候執行。相似的,還有gBinderInternalOffsets和gBinderProxyOffsets。所以,我們現∑ 在可以知道:

                ????env->SetIntField(obj,?gBinderOffsets.mObject,?(int)jbh);

                ? ? ? ? 的作用就是把JavaBBinderHolder的實⊙例地址,保存到Binder的mObject成員中。其實,類似這□樣的處理手法在Android中非冷哼一聲常常見,例如MessageQueue和NactiveMessageQueue。 android_os_Binder_destroy ? ? ? ? 理解了init,destory就不難理解了:

                static?void?android_os_Binder_destroy(JNIEnv*?env,?jobject?obj)
                {
                ????JavaBBinderHolder*?jbh?=?(JavaBBinderHolder*)
                ????????env->GetIntField(obj,?gBinderOffsets.mObject);//從Binder.mObject獲得jbh
                ????if?(jbh?!=?NULL)?{
                ????????env->SetIntField(obj,?gBinderOffsets.mObject,?0);
                ????????ALOGV("Java?Binder?%p:?removing?ref?on?holder?%p",?obj,?jbh);//設置Binder.mObject=0
                ????????jbh->decStrong((void*)android_os_Binder_init);//通過強引用計①數,控制自己的生命周期
                ????}?else?{
                ????????//?Encountering?an?uninitialized?binder?is?harmless.??All?it?means?is?that
                ????????//?the?Binder?was?only?partially?initialized?when?its?finalizer?ran?and?called
                ????????//?destroy().??The?Binder?could?be?partially?initialized?for?several?reasons.
                ????????//?For?example,?a?Binder?subclass?constructor?might?have?thrown?an?exception?before
                ????????//?it?could?delegate?to?its?superclass's?constructor.??Consequently?init()?would
                ????????//?not?have?been?called?and?the?holder?pointer?would?remain?NULL.
                ????????ALOGV("Java?Binder?%p:?ignoring?uninitialized?binder",?obj);
                ????}
                }

                JavaBBinderHolder ? ? ? ? JavaBBinderHolder的實↑現比較簡單:

                class?JavaBBinderHolder?:?public?RefBase
                {
                public:
                ????spget(JNIEnv*?env,?jobject?obj)
                ????{
                ????????AutoMutex?_l(mLock);
                ????????spb?=?mBinder.promote();
                ????????if?(b?==?NULL)?{
                ????????????b?=?new?JavaBBinder(env,?obj);//構造JavaBBinder實例,這裏的obj參數為java的Binder類
                ????????????mBinder?=?b;
                ????????????ALOGV("Creating?JavaBinder?%p?(refs?%p)?for?Object?%p,?weakCount=%d\n",
                ?????????????????b.get(),?b->getWeakRefs(),?obj,?b->getWeakRefs()->getWeakCount());
                ????????}
                
                ????????return?b;
                ????}
                
                ????spgetExisting()
                ????{
                ????????AutoMutex?_l(mLock);
                ????????return?mBinder.promote();
                ????}
                
                private:
                ????Mutex???????????mLock;
                ????wpmBinder;
                };

                ? ? ? ? 不過,它引入了下♀一個角色:JavaBBinder。 JavaBBinder

                class?JavaBBinder?:?public?BBinder
                {
                public:
                ????JavaBBinder(JNIEnv*?env,?jobject?object)
                ????????:?mVM(jnienv_to_javavm(env)),?mObject(env->NewGlobalRef(object))
                ????{
                ????????ALOGV("Creating?JavaBBinder?%p\n",?this);
                ????????android_atomic_inc(&gNumLocalRefs);
                ????????incRefsCreated(env);
                ????}
                
                ????bool????checkSubclass(const?void*?subclassID)?const
                ????{
                ????????return?subclassID?==?&gBinderOffsets;
                ????}
                
                ????jobject?object()?const
                ????{
                ????????return?mObject;
                ????}
                
                protected:
                ????virtual?~JavaBBinder()
                ????{
                ????????ALOGV("Destroying?JavaBBinder?%p\n",?this);
                ????????android_atomic_dec(&gNumLocalRefs);
                ????????JNIEnv*?env?=?javavm_to_jnienv(mVM);
                ????????env->DeleteGlobalRef(mObject);
                ????}
                
                ????virtual?status_t?onTransact(
                ????????uint32_t?code,?const?Parcel&?data,?Parcel*?reply,?uint32_t?flags?=?0)
                ????{
                ????????JNIEnv*?env?=?javavm_to_jnienv(mVM);
                
                ????????ALOGV("onTransact()?on?%p?calling?object?%p?in?env?%p?vm?%p\n",?this,?mObject,?env,?mVM);
                
                ????????IPCThreadState*?thread_state?=?IPCThreadState::self();
                ????????const?int?strict_policy_before?=?thread_state->getStrictModePolicy();
                ????????thread_state->setLastTransactionBinderFlags(flags);
                
                ????????//printf("Transact?from?%p?to?Java?code?sending:?",?this);
                ????????//data.print();
                ????????//printf("\n");
                ????????jboolean?res?=?env->CallBooleanMethod(mObject,?gBinderOffsets.mExecTransact,
                ????????????code,?(int32_t)&data,?(int32_t)reply,?flags);
                ????????jthrowable?excep?=?env->ExceptionOccurred();
                
                ????????if?(excep)?{
                ????????????report_exception(env,?excep,
                ????????????????"***?Uncaught?remote?exception!??"
                ????????????????"(Exceptions?are?not?yet?supported?across?processes.)");
                ????????????res?=?JNI_FALSE;
                
                ????????????/*?clean?up?JNI?local?ref?--?we?don't?return?to?Java?code?*/
                ????????????env->DeleteLocalRef(excep);
                ????????}
                
                ????????//?Restore?the?Java?binder?thread's?state?if?it?changed?while
                ????????//?processing?a?call?(as?it?would?if?the?Parcel's?header?had?a
                ????????//?new?policy?mask?and?Parcel.enforceInterface()?changed
                ????????//?it...)
                ????????const?int?strict_policy_after?=?thread_state->getStrictModePolicy();
                ????????if?(strict_policy_after?!=?strict_policy_before)?{
                ????????????//?Our?thread-local...
                ????????????thread_state->setStrictModePolicy(strict_policy_before);
                ????????????//?And?the?Java-level?thread-local...
                ????????????set_dalvik_blockguard_policy(env,?strict_policy_before);
                ????????}
                
                ????????jthrowable?excep2?=?env->ExceptionOccurred();
                ????????if?(excep2)?{
                ????????????report_exception(env,?excep2,
                ????????????????"***?Uncaught?exception?in?onBinderStrictModePolicyChange");
                ????????????/*?clean?up?JNI?local?ref?--?we?don't?return?to?Java?code?*/
                ????????????env->DeleteLocalRef(excep2);
                ????????}
                
                ????????//?Need?to?always?call?through?the?native?implementation?of
                ????????//?SYSPROPS_TRANSACTION.
                ????????if?(code?==?SYSPROPS_TRANSACTION)?{
                ????????????BBinder::onTransact(code,?data,?reply,?flags);
                ????????}
                
                ????????//aout?<<?"onTransact?to?Java?code;?result="?<<?res?<<?endl
                ????????//????<<?"Transact?from?"?<<?this?<<?"?to?Java?code?returning?"
                ????????//????<<?reply?<<?":?"?<<?*reply?<<?endl;
                ????????return?res?!=?JNI_FALSE???NO_ERROR?:?UNKNOWN_TRANSACTION;
                ????}
                
                ????virtual?status_t?dump(int?fd,?const?Vector&?args)
                ????{
                ????????return?0;
                ????}
                
                private:
                ????JavaVM*?const???mVM;
                ????jobject?const???mObject;
                };

                ? ? ? ? 原來JavaBBinder繼承自BBinder。現在我們終於看到◣了Native層的Binder接口。從前面幾→節的內容,我們知道,BBinder代表著用∴戶空間的Binder實體。所以,JavaBBinder也是代表用這順天盟戶空間的Binder實體。 ? ? ? ? 拋開其他次要的部分不談,我〖們只關註onTransact函數:

                ???virtual?status_t?onTransact(
                ????????uint32_t?code,?const?Parcel&?data,?Parcel*?reply,?uint32_t?flags?=?0)
                ????{
                ????????......
                
                ????????jboolean?res?=?env->CallBooleanMethod(mObject,?gBinderOffsets.mExecTransact,
                ????????????code,?(int32_t)&data,?(int32_t)reply,?flags);//調用Binder實例的execTransact方法
                
                ????????......
                ????}

                ? ? ? ? 用最簡單的視角去分析onTransact函數,我們會發◆現,它會調用Binder類的execTransact函數,而前面,我們有看到execTransact函⌒ 數會調用Binder類的onTransact函數,這樣,最終你要是想喝一杯就會執行Service的業務邏☆輯,處理Client的請求。至於JavaBBinder的onTransact函數何時被調用,看過√前面兩節內容的讀者應該就心中有數了,稍後我們會更加具體◣的分析。 ? ? ? ? 這樣,我們現在已經知〗道在Server端,native層的binder接●口是何如與Java接★口交互的。接下來,讓我ω 們看看Client端 BinderProxy ??????? BinderProxy類同樣在frameworks/base/core/android/os/Binder.java中:

                final?class?BinderProxy?implements?IBinder?{
                ????public?native?boolean?pingBinder();
                ????public?native?boolean?isBinderAlive();
                ????
                ????public?IInterface?queryLocalInterface(String?descriptor)?{
                ????????return?null;
                ????}
                ????
                ????public?native?String?getInterfaceDescriptor()?throws?RemoteException;
                ????public?native?boolean?transact(int?code,?Parcel?data,?Parcel?reply,
                ????????????int?flags)?throws?RemoteException;
                ????public?native?void?linkToDeath(DeathRecipient?recipient,?int?flags)
                ????????????throws?RemoteException;
                ????public?native?boolean?unlinkToDeath(DeathRecipient?recipient,?int?flags);
                
                ????public?void?dump(FileDescriptor?fd,?String[]?args)?throws?RemoteException?{
                ????????Parcel?data?=?Parcel.obtain();
                ????????Parcel?reply?=?Parcel.obtain();
                ????????data.writeFileDescriptor(fd);
                ????????data.writeStringArray(args);
                ????????try?{
                ????????????transact(DUMP_TRANSACTION,?data,?reply,?0);
                ????????????reply.readException();
                ????????}?finally?{
                ????????????data.recycle();
                ????????????reply.recycle();
                ????????}
                ????}
                ????
                ????public?void?dumpAsync(FileDescriptor?fd,?String[]?args)?throws?RemoteException?{
                ????????Parcel?data?=?Parcel.obtain();
                ????????Parcel?reply?=?Parcel.obtain();
                ????????data.writeFileDescriptor(fd);
                ????????data.writeStringArray(args);
                ????????try?{
                ????????????transact(DUMP_TRANSACTION,?data,?reply,?FLAG_ONEWAY);
                ????????????reply.readException();
                ????????}?finally?{
                ????????????data.recycle();
                ????????????reply.recycle();
                ????????}
                ????}
                
                ????BinderProxy()?{
                ????????mSelf?=?new?WeakReference(this);
                ????}
                ????
                ????@Override
                ????protected?void?finalize()?throws?Throwable?{
                ????????try?{
                ????????????destroy();
                ????????}?finally?{
                ????????????super.finalize();
                ????????}
                ????}
                ????
                ????private?native?final?void?destroy();
                ????
                ????private?static?final?void?sendDeathNotice(DeathRecipient?recipient)?{
                ????????if?(false)?Log.v("JavaBinder",?"sendDeathNotice?to?"?+?recipient);
                ????????try?{
                ????????????recipient.binderDied();
                ????????}
                ????????catch?(RuntimeException?exc)?{
                ????????????Log.w("BinderNative",?"Uncaught?exception?from?death?notification",
                ????????????????????exc);
                ????????}
                ????}
                ????
                ????final?private?WeakReference?mSelf;
                ????private?int?mObject;
                ????private?int?mOrgue;
                }

                ??????? 這裏,我們只△關心transact函數∞的實現:

                static?jboolean?android_os_BinderProxy_transact(JNIEnv*?env,?jobject?obj,
                ????????jint?code,?jobject?dataObj,?jobject?replyObj,?jint?flags)?//?throws?RemoteException
                {
                ????......
                
                ????IBinder*?target?=?(IBinder*)
                ????????env->GetIntField(obj,?gBinderProxyOffsets.mObject);//和前面介紹過的gBinderOffsets相似,gBinderProxyOffsets的mObject成員指向BinderProxy實例的mObject成員
                ????if?(target?==?NULL)?{
                ????????jniThrowException(env,?"java/lang/IllegalStateException",?"Binder?has?been?finalized!");
                ????????return?JNI_FALSE;
                ????}
                
                ????......
                
                ????status_t?err?=?target->transact(code,?*data,?reply,?flags);//關鍵ぷ的調用
                
                ????......
                }

                ??????? 從上面的代碼可以看到,BinderProxy.mObject成員中保存了C++的IBinder對∩象的指針,然就是我後通過這個IBinder對象調用transact函數,進行binder通信。transact函數的實現,上一個章節中有介紹,所以BinderProxy的分析也到此惡魔一族為止↘。
                總結 通常,我們(應用開發者)通過aidl來進行binder通信,而aidl實現了 XXXX接口的聲◣明XXXXStub的實現,是對於Binder類的繼承,通過onTransact函數來呼叫業務邏輯代碼XXXXStub.Proxy的實現,它擁有一個IBinder,通過這個IBinder來實現請求的轉發Binder類的mObject成員指向原◣生層的JavaBBinderHolder實例,而JavaBinderHolder實例的get函數,可以生成JavaBBinder實例,JavaBBinder繼承自BBinder,是Server端的Binder實體BinderProxy類的mObject成員指≡向原生層的IBinder實例,而IBinder通常□ 是一個BpBinder實例,是Client端的Binder代理
                ??????? 僅僅從以上的分析,可能大家無法把整個Java層和C++層Binder通信的過程理清楚,不過沒關系●,後面我們會分析神尊Service和Binder通信的關系。從中,我們應該可以看到╳一個完整的Java層Binder通信過程。

                我要點評