Android IPC机制详解Word文件下载.docx

上传人:b****6 文档编号:20878648 上传时间:2023-01-26 格式:DOCX 页数:14 大小:22.90KB
下载 相关 举报
Android IPC机制详解Word文件下载.docx_第1页
第1页 / 共14页
Android IPC机制详解Word文件下载.docx_第2页
第2页 / 共14页
Android IPC机制详解Word文件下载.docx_第3页
第3页 / 共14页
Android IPC机制详解Word文件下载.docx_第4页
第4页 / 共14页
Android IPC机制详解Word文件下载.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

Android IPC机制详解Word文件下载.docx

《Android IPC机制详解Word文件下载.docx》由会员分享,可在线阅读,更多相关《Android IPC机制详解Word文件下载.docx(14页珍藏版)》请在冰豆网上搜索。

Android IPC机制详解Word文件下载.docx

}

参数说明:

∙code是请求的ID号。

∙data是请求的参数。

∙reply是返回的结果。

∙flags一些额外的标识,如FLAG_ONEWAY。

通常为0。

transact只是简单的调用了IPCThreadState:

self()的transact,在IPCThreadState:

transact中:

status_tIPCThreadState:

transact(int32_thandle,

data,

Parcel*reply,uint32_tflags)

status_terr=data.errorCheck();

flags|=TF_ACCEPT_FDS;

IF_LOG_TRANSACTIONS(){

TextOutput:

Bundle_b(alog);

alog<

<

"

BC_TRANSACTIONthr"

<

(void*)pthread_self()<

/hand"

handle<

/code"

TypeCode(code)<

indent<

data<

dedent<

endl;

if(err==NO_ERROR){

LOG_ONEWAY("

>

SENDfrompid%duid%d%s"

getpid(),getuid(),

(flags&

TF_ONE_WAY)==0?

READREPLY"

:

ONEWAY"

);

err=writeTransactionData(BC_TRANSACTION,flags,handle,code,data,NULL);

if(err!

=NO_ERROR){

if(reply)reply->

setError(err);

return(mLastError=err);

if((flags&

TF_ONE_WAY)==0){

if(reply){

err=waitForResponse(reply);

}else{

ParcelfakeReply;

err=waitForResponse(&

fakeReply);

BR_REPLYthr"

;

if(reply)alog<

*reply<

elsealog<

(nonerequested)"

err=waitForResponse(NULL,NULL);

returnerr;

waitForResponse(Parcel*reply,status_t*acquireResult)

int32_tcmd;

int32_terr;

while

(1){

if((err=talkWithDriver())<

NO_ERROR)break;

err=mIn.errorCheck();

if(err<

if(mIn.dataAvail()==0)continue;

cmd=mIn.readInt32();

IF_LOG_COMMANDS(){

ProcessingwaitForResponseCommand:

getReturnString(cmd)<

switch(cmd){

caseBR_TRANSACTION_COMPLETE:

if(!

reply&

&

!

acquireResult)gotofinish;

break;

caseBR_DEAD_REPLY:

err=DEAD_OBJECT;

gotofinish;

caseBR_FAILED_REPLY:

err=FAILED_TRANSACTION;

caseBR_ACQUIRE_RESULT:

{

LOG_ASSERT(acquireResult!

=NULL,"

UnexpectedbrACQUIRE_RESULT"

constint32_tresult=mIn.readInt32();

acquireResult)continue;

*acquireResult=result?

NO_ERROR:

INVALID_OPERATION;

caseBR_REPLY:

binder_transaction_datatr;

err=mIn.read(&

tr,sizeof(tr));

LOG_ASSERT(err==NO_ERROR,"

NotenoughcommanddataforbrREPLY"

=NO_ERROR)gotofinish;

if((tr.flags&

TF_STATUS_CODE)==0){

reply->

ipcSetDataReference(

reinterpret_cast(tr.data.ptr.buffer),

tr.data_size,

reinterpret_cast(tr.data.ptr.offsets),

tr.offsets_size/sizeof(size_t),

freeBuffer,this);

err=*static_cast(tr.data.ptr.buffer);

freeBuffer(NULL,

tr.offsets_size/sizeof(size_t),this);

continue;

default:

err=executeCommand(cmd);

finish:

if(acquireResult)*acquireResult=err;

mLastError=err;

这里transact把请求经内核模块发送了给服务端,服务端处理完请求之后,沿原路返回结果给调用者。

这里也可以看出请求是同步操作,它会等待直到结果返回为止。

在BpBinder之上进行简单包装,我们可以得到与服务对象相同的接口,调用者无需要关心调用的对象是远程的还是本地的。

拿ServiceManager来说:

(frameworks/base/libs/utils/IServiceManager.cpp)

classBpServiceManager:

publicBpInterface

public:

BpServiceManager(constsp&

impl)

BpInterface(impl)

...

virtualstatus_taddService(constString16&

name,constsp&

service)

Parceldata,reply;

data.writeInterfaceToken(IServiceManager:

getInterfaceDescriptor());

data.writeString16(name);

data.writeStrongBinder(service);

status_terr=remote()->

transact(ADD_SERVICE_TRANSACTION,data,&

reply);

returnerr==NO_ERROR?

reply.readInt32():

err;

};

BpServiceManager实现了IServiceManager和IBinder两个接口,调用者可以把BpServiceManager的对象看作是一个IServiceManager对象或者IBinder对象。

当调用者把BpServiceManager对象当作IServiceManager对象使用时,所有的请求只是对BpBinder:

transact的封装。

这样的封装使得调用者不需要关心IServiceManager对象是本地的还是远程的了。

客户通过defaultServiceManager函数来创建BpServiceManager对象:

sp<

IServiceManager>

defaultServiceManager()

if(gDefaultServiceManager!

=NULL)returngDefaultServiceManager;

AutoMutex_l(gDefaultServiceManagerLock);

if(gDefaultServiceManager==NULL){

gDefaultServiceManager=interface_cast<

ProcessState:

getContextObject(NULL));

returngDefaultServiceManager;

先通过ProcessState:

getContextObject(NULL)创建一个Binder对象,然后通过interface_cast和IMPLEMENT_META_INTERFACE(ServiceManager,“android.os.IServiceManager”)把Binder对象包装成IServiceManager对象。

原理上等同于创建了一个BpServiceManager对象。

ProcessState:

getContextObject调用ProcessState:

getStrongProxyForHandle创建代理对象:

IBinder>

getStrongProxyForHandle(int32_thandle)

sp<

result;

AutoMutex_l(mLock);

handle_entry*e=lookupHandleLocked(handle);

if(e!

=NULL){

//WeneedtocreateanewBpBinderifthereisn'

tcurrentlyone,ORwe

//areunabletoacquireaweakreferenceonthiscurrentone.Seecomment

//ingetWeakProxyForHandle()formoreinfoaboutthis.

IBinder*b=e->

binder;

if(b==NULL||!

e->

refs->

attemptIncWeak(this)){

b=newBpBinder(handle);

e->

binder=b;

if(b)e->

refs=b->

getWeakRefs();

result=b;

//Thislittlebitofnastynessistoallowustoaddaprimary

//referencetotheremoteproxywhenthisteamdoesn'

thaveone

//butanotherteamissendingthehandletous.

result.force_set(b);

decWeak(this);

returnresult;

如果handle为空,默认为context_manager对象,context_manager实际上就是ServiceManager。

o服务端

服务端也要实现IBinder接口,BBinder类对IBinder接口提供了部分默认实现,其中transact的实现如下:

status_tBBinder:

data.setDataPosition(0);

status_terr=NO_ERROR;

switch(code){

casePING_TRANSACTION:

writeInt32(pingBinder());

err=onTransact(code,data,reply,flags);

if(reply!

setDataPosition(0);

PING_TRANSACTION请求用来检查对象是否还存在,这里简单的把pingBinder的返回值返回给调用者。

其它的请求交给onTransact处理。

onTransact是BBinder里声明的一个protected类型的虚函数,这个要求它的子类去实现。

比如CameraService里的实现如下:

status_tCameraService:

onTransact(

//permissionchecks...

caseBnCameraService:

CONNECT:

IPCThreadState*ipc=IPCThreadState:

self();

constintpid=ipc->

getCallingPid();

constintself_pid=getpid();

if(pid!

=self_pid){

//we'

recalledfromadifferentprocess,dotherealcheck

checkCallingPermission(

String16("

android.permission.CAMERA"

)))

constintuid=ipc->

getCallingUid();

LOGE("

PermissionDenial:

can'

tusethecamerapid=%d,uid=%d"

pid,uid);

returnPERMISSION_DENIED;

status_terr=BnCameraService:

onTransact(code,data,reply,flags);

LOGD("

+++onTransacterr%dcode%d"

err,code);

if(err==UNKNOWN_TRANSACTION||err==PERMISSION_DENIED){

//the'

service'

commandinterrogatesthisbinderforitsname,andthensuppliesit

//evenforthedebuggingcommands.thatmeansweneedtocheckforithere,using

//ISurfaceComposer(sincewedelegatedtheINTERFACE_TRANSACTIONhandlingto

//BnSurfaceComposerbeforefallingthroughtothiscode).

+++onTransactcode%d"

code);

CHECK_INTERFACE(ICameraService,data,reply);

switch(code){

case1000:

if(gWeakHeap!

=0){

sph=gWeakHeap.promote();

IMemoryHeap*p=gWeakHeap.unsafe_get();

CHECKINGWEAKREFERENCE%p(%p)"

h.get(),p);

if(h!

=0)

h->

printRefs();

boolattempt_to_delete=data.readInt32()==1;

if(attempt_to_delete){

//NOTSAFE!

DELETINGWEAKREFERENCE%p(%p)"

if(p)deletep;

returnNO_ERROR;

由此可见,服务端的onTransact是一个请求分发函数,它根据请求码(code)做相应的处理。

o消息循环

服务端(任何进程都可以作为服务端)有一个线程监听来自客户端的请求,并循环处理这些请求。

如果在主线程中处理请求,可以直接调用下面的函数:

IPCThreadState:

joinThreadPool(mIsMain);

如果想在非主线程中处理请求,可以按下列方式:

sp

proc=ProcessState:

if(proc->

supportsProcesses()){

LOGV("

Appprocess:

startingthreadpool./n"

proc->

startThreadPool();

startThreadPool的实现原理:

voidProcessState:

startThreadPool()

mThreadPoolStarted){

mThreadPoolStarted=true;

spawnPooledThread(true);

spawnPooledThread(boolisMain)

if(mThreadPoolStarted){

int32_ts=android_atomic_add(1,&

mThreadPoolSeq);

charbuf[32];

sprintf(buf,"

BinderThread#%d"

s);

Spawningnew

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 语文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1