Binder機制學(xué)習(xí)總結(jié)之Java接口部分
? ? ? ? 因為上一節(jié)service manager中,對于binder通信的客戶端(BpServiceManager)和服務(wù)端(service manager進程)已經(jīng)有比較詳細的解釋,所以,不再對于Binder通信的client端和server端做分析,有興趣的同學(xué)可以看看MediaPlayerService和MediaPlayer,網(wǎng)上很多資料有講解。
? ? ? ? 當(dāng)目前為止,所有的代碼都是以C/C++語言的,但是,App開發(fā)者通常使用Java語言,那么Java是如何使用Binder通信的呢?
AIDL ? ? ? ? 很多時候,我們是通過aidl(Android Interface Define Language)間接的使用Binder機制的。例如,我們準(zhǔn)備了下面這樣一個aidl文件:
package?com.ray.example;
interface?RInterface?{
????void?hello(String?message);
}? ? ? ?經(jīng)過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;
}? ? ? ? 編譯產(chǎn)生的java文件提供了三個對象:
RInterface接口:繼承自IInterface接口,并且有一個hello的成員函數(shù)。作為server和client之間的約定,雙方都會使用。
RInterface.Stub抽象類:繼承自Binder類,并且提供了onTransact函數(shù)的實現(xiàn),以及靜態(tài)函數(shù)asInterface。
RInterface.Stub.Proxy類:實現(xiàn)了RInterface接口,實現(xiàn)了hello函數(shù)。
XXXX.Stub ? ? ? ??主要由Server端實現(xiàn),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函數(shù)來提供具體的處理邏輯。而hello函數(shù)是如何被調(diào)用的呢?這就需要回顧RInterface.Stub類對于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)用時,hello函數(shù)會被調(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類的內(nèi)部實現(xiàn),我們稍后分析。 XXXX.Stub.Proxy ? ? ? ? 主要由Client端使用,顧名思義,擔(dān)當(dāng)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函數(shù)會構(gòu)造一個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。而調(diào)用Proxy對于hello的實現(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的類型為IBinder
_reply.readException();
}
finally?{
_reply.recycle();
_data.recycle();
}? ? ? ?很明顯的,是通過Binder機制轉(zhuǎn)發(fā)請求,但是mRemote是如何實現(xiàn)transaction函數(shù)的呢?我們暫時還不知道。 小結(jié) aidl文件編譯成java文件時,提供了三個對象:XXXX接口,這個接口根據(jù)aidl文件的內(nèi)容生成,作為通信雙方的約定。XXXX.Stub抽象類,這個抽象類繼承自Binder類。它實現(xiàn)了從Binder中讀取到數(shù)據(jù)以后,呼叫業(yè)務(wù)邏輯處理代碼的功能。Server端通過繼承并實現(xiàn)業(yè)務(wù)邏輯來使用它。XXXX.Stub.Proxy類,這個類封裝了一個IBinder接口,它實現(xiàn)了把Client端請求通過Binder發(fā)送到Server端的功能。Client可以通過XXXX.Stub.asInterface函數(shù)來獲得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類的聲明有點長,所以,這邊僅僅列出幾個重點函數(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端的進程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; ? ?}
? ? ? ? 到目前為止,我們似乎還沒發(fā)現(xiàn)Java的Binder類和native層的C++Binder接口存在什么聯(lián)系,不過,我們還沒看過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函數(shù)構(gòu)造了一個JavaBBinderHolder實例,看起來奧秘應(yīng)該就在這個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函數(shù)
????assert(gBinderOffsets.mExecTransact);
????gBinderOffsets.mObject
????????=?env->GetFieldID(clazz,?"mObject",?"I");//mObject指向Binder類的mObject成員
????assert(gBinderOffsets.mObject);
????return?AndroidRuntime::registerNativeMethods(//注冊原生函數(shù)
????????env,?kBinderPathName,
????????gBinderMethods,?NELEM(gBinderMethods));
}? ? ? ? 而register_android_os_Binder函數(shù)則會在Dalvik虛擬機啟動的時候執(zhí)行。相似的,還有g(shù)BinderInternalOffsets和gBinderProxyOffsets。所以,我們現(xiàn)在可以知道:
????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);//設(shè)置Binder.mObject=0
????????jbh->decStrong((void*)android_os_Binder_init);//通過強引用計數(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的實現(xià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實例,這里的obj參數(shù)為java的Binder類
????????????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;
};? ? ? ? 不過,它引入了下一個角色: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;
};? ? ? ? 原來JavaBBinder繼承自BBinder。現(xiàn)在我們終于看到了Native層的Binder接口。從前面幾節(jié)的內(nèi)容,我們知道,BBinder代表著用戶空間的Binder實體。所以,JavaBBinder也是代表用戶空間的Binder實體。 ? ? ? ? 拋開其他次要的部分不談,我們只關(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實例的execTransact方法
????????......
????}? ? ? ? 用最簡單的視角去分析onTransact函數(shù),我們會發(fā)現(xiàn),它會調(diào)用Binder類的execTransact函數(shù),而前面,我們有看到execTransact函數(shù)會調(diào)用Binder類的onTransact函數(shù),這樣,最終就會執(zhí)行Service的業(yè)務(wù)邏輯,處理Client的請求。至于JavaBBinder的onTransact函數(shù)何時被調(diào)用,看過前面兩節(jié)內(nèi)容的讀者應(yīng)該就心中有數(shù)了,稍后我們會更加具體的分析。 ? ? ? ? 這樣,我們現(xiàn)在已經(jīng)知道在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;
}??????? 這里,我們只關(guān)心transact函數(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);//和前面介紹過的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);//關(guān)鍵的調(diào)用
????......
}??????? 從上面的代碼可以看到,BinderProxy.mObject成員中保存了C++的IBinder對象的指針,然后通過這個IBinder對象調(diào)用transact函數(shù),進行binder通信。transact函數(shù)的實現(xiàn),上一個章節(jié)中有介紹,所以BinderProxy的分析也到此為止。
總結(jié)
通常,我們(應(yīng)用開發(fā)者)通過aidl來進行binder通信,而aidl實現(xiàn)了
XXXX接口的聲明XXXXStub的實現(xiàn),是對于Binder類的繼承,通過onTransact函數(shù)來呼叫業(yè)務(wù)邏輯代碼XXXXStub.Proxy的實現(xiàn),它擁有一個IBinder,通過這個IBinder來實現(xiàn)請求的轉(zhuǎn)發(fā)Binder類的mObject成員指向原生層的JavaBBinderHolder實例,而JavaBinderHolder實例的get函數(shù),可以生成JavaBBinder實例,JavaBBinder繼承自BBinder,是Server端的Binder實體BinderProxy類的mObject成員指向原生層的IBinder實例,而IBinder通常是一個BpBinder實例,是Client端的Binder代理
??????? 僅僅從以上的分析,可能大家無法把整個Java層和C++層Binder通信的過程理清楚,不過沒關(guān)系,后面我們會分析Service和Binder通信的關(guān)系。從中,我們應(yīng)該可以看到一個完整的Java層Binder通信過程。





