Android IPC机制详解Word文件下载.docx
《Android IPC机制详解Word文件下载.docx》由会员分享,可在线阅读,更多相关《Android IPC机制详解Word文件下载.docx(14页珍藏版)》请在冰豆网上搜索。
![Android IPC机制详解Word文件下载.docx](https://file1.bdocx.com/fileroot1/2023-1/22/efa6c7c0-be9e-4385-b42c-0489be24daeb/efa6c7c0-be9e-4385-b42c-0489be24daeb1.gif)
}
参数说明:
∙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