www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁(yè) > 芯聞號(hào) > 充電吧
[導(dǎo)讀]? ? ? ? 因?yàn)樯弦还?jié)service manager中,對(duì)于binder通信的客戶端(BpServiceManager)和服務(wù)端(service manager進(jìn)程)已經(jīng)有比較詳細(xì)的解釋?zhuān)?,?

? ? ? ? 因?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ò)程。

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專(zhuān)欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車(chē)的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車(chē)技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車(chē)工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車(chē)。 SODA V工具的開(kāi)發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車(chē) 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來(lái)越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來(lái)越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開(kāi)幕式在貴陽(yáng)舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語(yǔ)權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉