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

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

? ? ? ? 因?yàn)樯弦还?jié)service manager中,對(duì)于binder通信的客戶端(BpServiceManager)和服務(wù)端(service manager進(jìn)程)已經(jīng)有比較詳細(xì)的解釋,所以,不再對(duì)于Binder通信的client端和server端做分析,有興趣的同學(xué)可以看看MediaPlayerService和MediaPlayer,網(wǎng)上很多資料有講解。

? ? ? ? 當(dāng)目前為止,所有的代碼都是以C/C++語言的,但是,App開發(fā)者通常使用Java語言,那么Java是如何使用Binder通信的呢?

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

package?com.ray.example;

interface?RInterface?{
????void?hello(String?message);
}

? ? ? ?經(jīng)過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抽象類:繼承自Binder類,并且提供了onTransact函數(shù)的實(shí)現(xiàn),以及靜態(tài)函數(shù)asInterface。

RInterface.Stub.Proxy類:實(shí)現(xiàn)了RInterface接口,實(shí)現(xiàn)了hello函數(shù)。

XXXX.Stub ? ? ? ??主要由Server端實(shí)現(xiàn),Server端通過繼承本類,來提供具體的處理邏輯。通常,在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);
????}
}

? ? ? ? 這里通過重載來hello函數(shù)來提供具體的處理邏輯。而hello函數(shù)是如何被調(diào)用的呢?這就需要回顧RInterface.Stub類對(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類的內(nèi)部實(shí)現(xiàn),我們稍后分析。 XXXX.Stub.Proxy ? ? ? ? 主要由Client端使用,顧名思義,擔(dān)當(dāng)Server的代理角色。 ? ? ? ? 通常,在Clent端,會(huì)有類似如下的代碼:

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類的實(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的類型為IBinder
_reply.readException();
}
finally?{
_reply.recycle();
_data.recycle();
}

? ? ? ?很明顯的,是通過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抽象類,這個(gè)抽象類繼承自Binder類。它實(shí)現(xiàn)了從Binder中讀取到數(shù)據(jù)以后,呼叫業(yè)務(wù)邏輯處理代碼的功能。Server端通過繼承并實(shí)現(xiàn)業(yè)務(wù)邏輯來使用它。XXXX.Stub.Proxy類,這個(gè)類封裝了一個(gè)IBinder接口,它實(shí)現(xiàn)了把Client端請(qǐng)求通過Binder發(fā)送到Server端的功能。Client可以通過XXXX.Stub.asInterface函數(shù)來獲得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;
????//注銷死亡通知
????public?boolean?unlinkToDeath(DeathRecipient?recipient,?int?flags);
}

Binder類 ? ? ? ? ? ? ? ? Binder類的聲明有點(diǎn)長,所以,這邊僅僅列出幾個(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; ? ?}

? ? ? ? 到目前為止,我們似乎還沒發(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)造了一個(gè)JavaBBinderHolder實(shí)例,看起來奧秘應(yīng)該就在這個(gè)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;

? ? ? ? 它有三個(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類
????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(//注冊(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í),類似這樣的處理手法在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);//通過強(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)比較簡單:

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類
????????????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;
};

? ? ? ? 不過,它引入了下一個(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;
};

? ? ? ? 原來JavaBBinder繼承自BBinder。現(xiàn)在我們終于看到了Native層的Binder接口。從前面幾節(jié)的內(nèi)容,我們知道,BBinder代表著用戶空間的Binder實(shí)體。所以,JavaBBinder也是代表用戶空間的Binder實(shí)體。 ? ? ? ? 拋開其他次要的部分不談,我們只關(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方法

????????......
????}

? ? ? ? 用最簡單的視角去分析onTransact函數(shù),我們會(huì)發(fā)現(xiàn),它會(huì)調(diào)用Binder類的execTransact函數(shù),而前面,我們有看到execTransact函數(shù)會(huì)調(diào)用Binder類的onTransact函數(shù),這樣,最終就會(huì)執(zhí)行Service的業(yè)務(wù)邏輯,處理Client的請(qǐng)求。至于JavaBBinder的onTransact函數(shù)何時(shí)被調(diào)用,看過前面兩節(jié)內(nèi)容的讀者應(yīng)該就心中有數(shù)了,稍后我們會(huì)更加具體的分析。 ? ? ? ? 這樣,我們現(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ù)的實(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實(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ì)象的指針,然后通過這個(gè)IBinder對(duì)象調(diào)用transact函數(shù),進(jìn)行binder通信。transact函數(shù)的實(shí)現(xiàn),上一個(gè)章節(jié)中有介紹,所以BinderProxy的分析也到此為止。
總結(jié) 通常,我們(應(yīng)用開發(fā)者)通過aidl來進(jìn)行binder通信,而aidl實(shí)現(xiàn)了 XXXX接口的聲明XXXXStub的實(shí)現(xiàn),是對(duì)于Binder類的繼承,通過onTransact函數(shù)來呼叫業(yè)務(wù)邏輯代碼XXXXStub.Proxy的實(shí)現(xiàn),它擁有一個(gè)IBinder,通過這個(gè)IBinder來實(shí)現(xiàn)請(qǐng)求的轉(zhuǎn)發(fā)Binder類的mObject成員指向原生層的JavaBBinderHolder實(shí)例,而JavaBinderHolder實(shí)例的get函數(shù),可以生成JavaBBinder實(shí)例,JavaBBinder繼承自BBinder,是Server端的Binder實(shí)體BinderProxy類的mObject成員指向原生層的IBinder實(shí)例,而IBinder通常是一個(gè)BpBinder實(shí)例,是Client端的Binder代理
??????? 僅僅從以上的分析,可能大家無法把整個(gè)Java層和C++層Binder通信的過程理清楚,不過沒關(guān)系,后面我們會(huì)分析Service和Binder通信的關(guān)系。從中,我們應(yīng)該可以看到一個(gè)完整的Java層Binder通信過程。

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

LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: 驅(qū)動(dòng)電源

在工業(yè)自動(dòng)化蓬勃發(fā)展的當(dāng)下,工業(yè)電機(jī)作為核心動(dòng)力設(shè)備,其驅(qū)動(dòng)電源的性能直接關(guān)系到整個(gè)系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動(dòng)勢(shì)抑制與過流保護(hù)是驅(qū)動(dòng)電源設(shè)計(jì)中至關(guān)重要的兩個(gè)環(huán)節(jié),集成化方案的設(shè)計(jì)成為提升電機(jī)驅(qū)動(dòng)性能的關(guān)鍵。

關(guān)鍵字: 工業(yè)電機(jī) 驅(qū)動(dòng)電源

LED 驅(qū)動(dòng)電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個(gè)照明設(shè)備的使用壽命。然而,在實(shí)際應(yīng)用中,LED 驅(qū)動(dòng)電源易損壞的問題卻十分常見,不僅增加了維護(hù)成本,還影響了用戶體驗(yàn)。要解決這一問題,需從設(shè)計(jì)、生...

關(guān)鍵字: 驅(qū)動(dòng)電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動(dòng)電源的公式,電感內(nèi)電流波動(dòng)大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關(guān)鍵字: LED 設(shè)計(jì) 驅(qū)動(dòng)電源

電動(dòng)汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產(chǎn)業(yè)的重要發(fā)展方向。電動(dòng)汽車的核心技術(shù)之一是電機(jī)驅(qū)動(dòng)控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機(jī)驅(qū)動(dòng)系統(tǒng)中的關(guān)鍵元件,其性能直接影響到電動(dòng)汽車的動(dòng)力性能和...

關(guān)鍵字: 電動(dòng)汽車 新能源 驅(qū)動(dòng)電源

在現(xiàn)代城市建設(shè)中,街道及停車場(chǎng)照明作為基礎(chǔ)設(shè)施的重要組成部分,其質(zhì)量和效率直接關(guān)系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進(jìn)步,高亮度白光發(fā)光二極管(LED)因其獨(dú)特的優(yōu)勢(shì)逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關(guān)鍵字: 發(fā)光二極管 驅(qū)動(dòng)電源 LED

LED通用照明設(shè)計(jì)工程師會(huì)遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關(guān)鍵字: LED 驅(qū)動(dòng)電源 功率因數(shù)校正

在LED照明技術(shù)日益普及的今天,LED驅(qū)動(dòng)電源的電磁干擾(EMI)問題成為了一個(gè)不可忽視的挑戰(zhàn)。電磁干擾不僅會(huì)影響LED燈具的正常工作,還可能對(duì)周圍電子設(shè)備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來解決L...

關(guān)鍵字: LED照明技術(shù) 電磁干擾 驅(qū)動(dòng)電源

開關(guān)電源具有效率高的特性,而且開關(guān)電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機(jī)重量也有所下降,所以,現(xiàn)在的LED驅(qū)動(dòng)電源

關(guān)鍵字: LED 驅(qū)動(dòng)電源 開關(guān)電源

LED驅(qū)動(dòng)電源是把電源供應(yīng)轉(zhuǎn)換為特定的電壓電流以驅(qū)動(dòng)LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: LED 隧道燈 驅(qū)動(dòng)電源
關(guān)閉