Binder機(jī)制學(xué)習(xí)總結(jié)之Java接口部分
? ? ? ? 因?yàn)樯弦还?jié)service manager中,對(duì)于binder通信的客戶端(BpServiceManager)和服務(wù)端(service manager進(jìn)程)已經(jīng)有比較詳細(xì)的解釋?zhuān)裕辉賹?duì)于Binder通信的client端和server端做分析,有興趣的同學(xué)可以看看MediaPlayerService和MediaPlayer,網(wǎng)上很多資料有講解。
? ? ? ? 當(dāng)目前為止,所有的代碼都是以C/C++語(yǔ)言的,但是,App開(kāi)發(fā)者通常使用Java語(yǔ)言,那么Java是如何使用Binder通信的呢?
AIDL ? ? ? ? 很多時(shí)候,我們是通過(guò)aidl(Android Interface Define Language)間接的使用Binder機(jī)制的。例如,我們準(zhǔn)備了下面這樣一個(gè)aidl文件:
package?com.ray.example; interface?RInterface?{ ????void?hello(String?message); }
? ? ? ?經(jīng)過(guò)IDE的編譯,我們會(huì)得到下面這樣的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; }
? ? ? ? 編譯產(chǎn)生的java文件提供了三個(gè)對(duì)象:
RInterface接口:繼承自IInterface接口,并且有一個(gè)hello的成員函數(shù)。作為server和client之間的約定,雙方都會(huì)使用。
RInterface.Stub抽象類(lèi):繼承自Binder類(lèi),并且提供了onTransact函數(shù)的實(shí)現(xiàn),以及靜態(tài)函數(shù)asInterface。
RInterface.Stub.Proxy類(lèi):實(shí)現(xiàn)了RInterface接口,實(shí)現(xiàn)了hello函數(shù)。
XXXX.Stub ? ? ? ??主要由Server端實(shí)現(xiàn),Server端通過(guò)繼承本類(lèi),來(lái)提供具體的處理邏輯。通常,在Server端,我們會(huì)有如下代碼:
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); ????} }
? ? ? ? 這里通過(guò)重載來(lái)hello函數(shù)來(lái)提供具體的處理邏輯。而hello函數(shù)是如何被調(diào)用的呢?這就需要回顧RInterface.Stub類(lèi)對(duì)于onTransact函數(shù)的重載:
@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); }
? ? ? ? 當(dāng)onTransact函數(shù)被以特定的參數(shù)調(diào)用時(shí),hello函數(shù)會(huì)被調(diào)用:
static?final?int?TRANSACTION_hello?=?(android.os.IBinder.FIRST_CALL_TRANSACTION?+?0);
? ? ? ? Android系統(tǒng)約定,code必須大于等于
????int?FIRST_CALL_TRANSACTION??=?0x00000001;
? ? ? ? 并且,小于等于
????int?LAST_CALL_TRANSACTION???=?0x00ffffff;
? ? ? ? 否則,code可能和Binder協(xié)議的一些保留code沖突。 ? ? ? ? 至于onTransact函數(shù)是如何被調(diào)用,就需要涉及到Binder類(lèi)的內(nèi)部實(shí)現(xiàn),我們稍后分析。 XXXX.Stub.Proxy ? ? ? ? 主要由Client端使用,顧名思義,擔(dān)當(dāng)Server的代理角色。 ? ? ? ? 通常,在Clent端,會(huì)有類(lèi)似如下的代碼:
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函數(shù)會(huì)構(gòu)造一個(gè)RInterface.Stub.Proxy類(lèi)的實(shí)例,并返回:
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實(shí)際上是RInterface.Stub.Proxy。而調(diào)用Proxy對(duì)于hello的實(shí)現(xiàn):
@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的類(lèi)型為IBinder _reply.readException(); } finally?{ _reply.recycle(); _data.recycle(); }
? ? ? ?很明顯的,是通過(guò)Binder機(jī)制轉(zhuǎn)發(fā)請(qǐng)求,但是mRemote是如何實(shí)現(xiàn)transaction函數(shù)的呢?我們暫時(shí)還不知道。 小結(jié) aidl文件編譯成java文件時(shí),提供了三個(gè)對(duì)象:XXXX接口,這個(gè)接口根據(jù)aidl文件的內(nèi)容生成,作為通信雙方的約定。XXXX.Stub抽象類(lèi),這個(gè)抽象類(lèi)繼承自Binder類(lèi)。它實(shí)現(xiàn)了從Binder中讀取到數(shù)據(jù)以后,呼叫業(yè)務(wù)邏輯處理代碼的功能。Server端通過(guò)繼承并實(shí)現(xiàn)業(yè)務(wù)邏輯來(lái)使用它。XXXX.Stub.Proxy類(lèi),這個(gè)類(lèi)封裝了一個(gè)IBinder接口,它實(shí)現(xiàn)了把Client端請(qǐng)求通過(guò)Binder發(fā)送到Server端的功能。Client可以通過(guò)XXXX.Stub.asInterface函數(shù)來(lái)獲得XXXX.Stub.Proxy實(shí)例。 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; ????//進(jìn)行binder通信 ????public?boolean?transact(int?code,?Parcel?data,?Parcel?reply,?int?flags) ????????throws?RemoteException; ????//死亡通知 ????public?interface?DeathRecipient?{ ????????public?void?binderDied(); ????} ????//注冊(cè)死亡通知 ????public?void?linkToDeath(DeathRecipient?recipient,?int?flags) ????????????throws?RemoteException; ????//注銷(xiāo)死亡通知 ????public?boolean?unlinkToDeath(DeathRecipient?recipient,?int?flags); }
Binder類(lèi) ? ? ? ? ? ? ? ? Binder類(lèi)的聲明有點(diǎn)長(zhǎng),所以,這邊僅僅列出幾個(gè)重點(diǎn)函數(shù):
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端的進(jìn)程id ????public?static?final?native?int?getCallingPid(); ????//?client端的用戶id ????public?static?final?native?int?getCallingUid();???? ????//?清除client端的進(jìn)程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; ? ?}
? ? ? ? 到目前為止,我們似乎還沒(méi)發(fā)現(xiàn)Java的Binder類(lèi)和native層的C++Binder接口存在什么聯(lián)系,不過(guò),我們還沒(méi)看過(guò)Binder類(lèi)的原生方法。 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函數(shù)構(gòu)造了一個(gè)JavaBBinderHolder實(shí)例,看起來(lái)奧秘應(yīng)該就在這個(gè)JavaBBinderHolder中了。不過(guò),在此之前,我們先解釋下
????env->SetIntField(obj,?gBinderOffsets.mObject,?(int)jbh);
? ? ? ?首先,需要從gBinderoffsets變量說(shuō)起:
static?struct?bindernative_offsets_t { ????//?Class?state. ????jclass?mClass; ????jmethodID?mExecTransact; ????//?Object?state. ????jfieldID?mObject; }?gBinderOffsets;
? ? ? ? 它有三個(gè)成員。而這三個(gè)成員的含義,我們可以從下面的代碼中了解:
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類(lèi) ????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類(lèi)的execTrasaction函數(shù) ????assert(gBinderOffsets.mExecTransact); ????gBinderOffsets.mObject ????????=?env->GetFieldID(clazz,?"mObject",?"I");//mObject指向Binder類(lèi)的mObject成員 ????assert(gBinderOffsets.mObject); ????return?AndroidRuntime::registerNativeMethods(//注冊(cè)原生函數(shù) ????????env,?kBinderPathName, ????????gBinderMethods,?NELEM(gBinderMethods)); }
? ? ? ? 而register_android_os_Binder函數(shù)則會(huì)在Dalvik虛擬機(jī)啟動(dòng)的時(shí)候執(zhí)行。相似的,還有g(shù)BinderInternalOffsets和gBinderProxyOffsets。所以,我們現(xiàn)在可以知道:
????env->SetIntField(obj,?gBinderOffsets.mObject,?(int)jbh);
? ? ? ? 的作用就是把JavaBBinderHolder的實(shí)例地址,保存到Binder的mObject成員中。其實(shí),類(lèi)似這樣的處理手法在Android中非常常見(jiàn),例如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);//設(shè)置Binder.mObject=0 ????????jbh->decStrong((void*)android_os_Binder_init);//通過(guò)強(qiáng)引用計(jì)數(shù),控制自己的生命周期 ????}?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的實(shí)現(xiàn)比較簡(jiǎn)單:
class?JavaBBinderHolder?:?public?RefBase { public: ????spget(JNIEnv*?env,?jobject?obj) ????{ ????????AutoMutex?_l(mLock); ????????spb?=?mBinder.promote(); ????????if?(b?==?NULL)?{ ????????????b?=?new?JavaBBinder(env,?obj);//構(gòu)造JavaBBinder實(shí)例,這里的obj參數(shù)為java的Binder類(lèi) ????????????mBinder?=?b; ????????????ALOGV("Creating?JavaBinder?%p?(refs?%p)?for?Object?%p,?weakCount=%dn", ?????????????????b.get(),?b->getWeakRefs(),?obj,?b->getWeakRefs()->getWeakCount()); ????????} ????????return?b; ????} ????spgetExisting() ????{ ????????AutoMutex?_l(mLock); ????????return?mBinder.promote(); ????} private: ????Mutex???????????mLock; ????wpmBinder; };
? ? ? ? 不過(guò),它引入了下一個(gè)角色:JavaBBinder。 JavaBBinder
class?JavaBBinder?:?public?BBinder { public: ????JavaBBinder(JNIEnv*?env,?jobject?object) ????????:?mVM(jnienv_to_javavm(env)),?mObject(env->NewGlobalRef(object)) ????{ ????????ALOGV("Creating?JavaBBinder?%pn",?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?%pn",?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?%pn",?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; };
? ? ? ? 原來(lái)JavaBBinder繼承自BBinder?,F(xiàn)在我們終于看到了Native層的Binder接口。從前面幾節(jié)的內(nèi)容,我們知道,BBinder代表著用戶空間的Binder實(shí)體。所以,JavaBBinder也是代表用戶空間的Binder實(shí)體。 ? ? ? ? 拋開(kāi)其他次要的部分不談,我們只關(guān)注onTransact函數(shù):
???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);//調(diào)用Binder實(shí)例的execTransact方法 ????????...... ????}
? ? ? ? 用最簡(jiǎn)單的視角去分析onTransact函數(shù),我們會(huì)發(fā)現(xiàn),它會(huì)調(diào)用Binder類(lèi)的execTransact函數(shù),而前面,我們有看到execTransact函數(shù)會(huì)調(diào)用Binder類(lèi)的onTransact函數(shù),這樣,最終就會(huì)執(zhí)行Service的業(yè)務(wù)邏輯,處理Client的請(qǐng)求。至于JavaBBinder的onTransact函數(shù)何時(shí)被調(diào)用,看過(guò)前面兩節(jié)內(nèi)容的讀者應(yīng)該就心中有數(shù)了,稍后我們會(huì)更加具體的分析。 ? ? ? ? 這樣,我們現(xiàn)在已經(jīng)知道在Server端,native層的binder接口是何如與Java接口交互的。接下來(lái),讓我們看看Client端 BinderProxy ??????? BinderProxy類(lèi)同樣在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; }
??????? 這里,我們只關(guān)心transact函數(shù)的實(shí)現(xiàn):
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);//和前面介紹過(guò)的gBinderOffsets相似,gBinderProxyOffsets的mObject成員指向BinderProxy實(shí)例的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);//關(guān)鍵的調(diào)用 ????...... }
??????? 從上面的代碼可以看到,BinderProxy.mObject成員中保存了C++的IBinder對(duì)象的指針,然后通過(guò)這個(gè)IBinder對(duì)象調(diào)用transact函數(shù),進(jìn)行binder通信。transact函數(shù)的實(shí)現(xiàn),上一個(gè)章節(jié)中有介紹,所以BinderProxy的分析也到此為止。
總結(jié)
通常,我們(應(yīng)用開(kāi)發(fā)者)通過(guò)aidl來(lái)進(jìn)行binder通信,而aidl實(shí)現(xiàn)了
XXXX接口的聲明XXXXStub的實(shí)現(xiàn),是對(duì)于Binder類(lèi)的繼承,通過(guò)onTransact函數(shù)來(lái)呼叫業(yè)務(wù)邏輯代碼XXXXStub.Proxy的實(shí)現(xiàn),它擁有一個(gè)IBinder,通過(guò)這個(gè)IBinder來(lái)實(shí)現(xiàn)請(qǐng)求的轉(zhuǎn)發(fā)Binder類(lèi)的mObject成員指向原生層的JavaBBinderHolder實(shí)例,而JavaBinderHolder實(shí)例的get函數(shù),可以生成JavaBBinder實(shí)例,JavaBBinder繼承自BBinder,是Server端的Binder實(shí)體BinderProxy類(lèi)的mObject成員指向原生層的IBinder實(shí)例,而IBinder通常是一個(gè)BpBinder實(shí)例,是Client端的Binder代理
??????? 僅僅從以上的分析,可能大家無(wú)法把整個(gè)Java層和C++層Binder通信的過(guò)程理清楚,不過(guò)沒(méi)關(guān)系,后面我們會(huì)分析Service和Binder通信的關(guān)系。從中,我們應(yīng)該可以看到一個(gè)完整的Java層Binder通信過(guò)程。