Android Service的绑定过程.docx

上传人:b****6 文档编号:3153537 上传时间:2022-11-18 格式:DOCX 页数:16 大小:126.24KB
下载 相关 举报
Android Service的绑定过程.docx_第1页
第1页 / 共16页
Android Service的绑定过程.docx_第2页
第2页 / 共16页
Android Service的绑定过程.docx_第3页
第3页 / 共16页
Android Service的绑定过程.docx_第4页
第4页 / 共16页
Android Service的绑定过程.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

Android Service的绑定过程.docx

《Android Service的绑定过程.docx》由会员分享,可在线阅读,更多相关《Android Service的绑定过程.docx(16页珍藏版)》请在冰豆网上搜索。

Android Service的绑定过程.docx

AndroidService的绑定过程

AndroidService的绑定过程

通常我们使用Service都要和它通信,当想要与Service通信的时候,那么Service要处于绑定状态的。

然后客户端可以拿到一个Binder与服务端进行通信,这个过程是很自然的。

那你真的了解过Service的绑定过程吗?

为什么可以是Binder和Service通信?

同样的先看一张图大致了解一下,灰色背景框起来的是同一个类的方法,如下:

我们知道调用Context的bindService方法即可绑定一个Service,而ContextImpl是Context的实现类。

那接下来就从源码的角度分析Service的绑定过程。

当然是从ContextImpl的bindService方法开始,如下:

@Override

publicbooleanbindService(Intentservice,ServiceConnectionconn,

intflags){

warnIfCallingFromSystemProcess();

returnbindServiceCommon(service,conn,flags,mMainThread.getHandler(),

Process.myUserHandle());

}

在bindService方法中又会转到bindServiceCommon方法,将Intent,ServiceConnection对象传进。

那就看看bindServiceCommon方法的实现。

privatebooleanbindServiceCommon(Intentservice,ServiceConnectionconn,intflags,Handler

handler,UserHandleuser){

IServiceConnectionsd;

if(conn==null){

thrownewIllegalArgumentException("connectionisnull");

}

if(mPackageInfo!

=null){

sd=mPackageInfo.getServiceDispatcher(conn,getOuterContext(),handler,flags);

}else{

thrownewRuntimeException("Notsupportedinsystemcontext");

}

validateServiceIntent(service);

try{

IBindertoken=getActivityToken();

if(token==null&&(flags&BIND_AUTO_CREATE)==0&&mPackageInfo!

=null

&&mPackageInfo.getApplicationInfo().targetSdkVersion

flags|=BIND_WAIVE_PRIORITY;

}

service.prepareToLeaveProcess(this);

intres=ActivityManagerNative.getDefault().bindService(

mMainThread.getApplicationThread(),getActivityToken(),service,

service.resolveTypeIfNeeded(getContentResolver()),

sd,flags,getOpPackageName(),user.getIdentifier());

if(res<0){

thrownewSecurityException(

"Notallowedtobindtoservice"+service);

}

returnres!

=0;

}catch(RemoteExceptione){

throwe.rethrowFromSystemServer();

}

}

在上述代码中,调用了mPackageInfo(LoadedApk对象)的getServiceDispatcher方法。

从getServiceDispatcher方法的名字可以看出是获取一个“服务分发者”。

其实是根据这个“服务分发者”获取到一个Binder对象的。

那现在就看到getServiceDispatcher方法的实现。

publicfinalIServiceConnectiongetServiceDispatcher(ServiceConnectionc,

Contextcontext,Handlerhandler,intflags){

synchronized(mServices){

LoadedApk.ServiceDispatchersd=null;

ArrayMapmap=mServices.get(context);

if(map!

=null){

sd=map.get(c);

}

if(sd==null){

sd=newServiceDispatcher(c,context,handler,flags);

if(map==null){

map=newArrayMap();

mServices.put(context,map);

}

map.put(c,sd);

}else{

sd.validate(context,handler);

}

returnsd.getIServiceConnection();

}

}

从getServiceDispatcher方法的实现可以知道,ServiceConnection和ServiceDispatcher构成了映射关系。

当存储集合不为空的时候,根据传进的key,也就是ServiceConnection,来取出对应的ServiceDispatcher对象。

当取出ServiceDispatcher对象后,最后一行代码是关键,

returnsd.getIServiceConnection();

调用了ServiceDispatcher对象的getIServiceConnection方法。

这个方法肯定是获取一个IServiceConnection的。

IServiceConnectiongetIServiceConnection(){

returnmIServiceConnection;

}

那么mIServiceConnection是什么?

现在就可以来看下ServiceDispatcher类了。

ServiceDispatcher是LoadedApk的内部类,里面封装了InnerConnection和ServiceConnection。

如下:

staticfinalclassServiceDispatcher{

privatefinalServiceDispatcher.InnerConnectionmIServiceConnection;

privatefinalServiceConnectionmConnection;

privatefinalContextmContext;

privatefinalHandlermActivityThread;

privatefinalServiceConnectionLeakedmLocation;

privatefinalintmFlags;

privateRuntimeExceptionmUnbindLocation;

privatebooleanmForgotten;

privatestaticclassConnectionInfo{

IBinderbinder;

IBinder.DeathRecipientdeathMonitor;

}

privatestaticclassInnerConnectionextendsIServiceConnection.Stub{

finalWeakReferencemDispatcher;

InnerConnection(LoadedApk.ServiceDispatchersd){

mDispatcher=newWeakReference(sd);

}

publicvoidconnected(ComponentNamename,IBinderservice)throwsRemoteException{

LoadedApk.ServiceDispatchersd=mDispatcher.get();

if(sd!

=null){

sd.connected(name,service);

}

}

}

privatefinalArrayMapmActiveConnections

=newArrayMap();

ServiceDispatcher(ServiceConnectionconn,

Contextcontext,HandleractivityThread,intflags){

mIServiceConnection=newInnerConnection(this);

mConnection=conn;

mContext=context;

mActivityThread=activityThread;

mLocation=newServiceConnectionLeaked(null);

mLocation.fillInStackTrace();

mFlags=flags;

}

//代码省略

}

先看到ServiceDispatcher的构造方法,一个ServiceDispatcher关联一个InnerConnection对象。

而InnerConnection呢?

,它是一个Binder,有一个很重要的connected方法。

至于为什么要用Binder,因为与Service通信可能是跨进程的。

好,到了这里先总结一下:

调用bindService方法绑定服务,会转到bindServiceCommon方法。

在bindServiceCommon方法中,会调用LoadedApk的getServiceDispatcher方法,并将ServiceConnection传进,根据这个ServiceConnection取出与其映射的ServiceDispatc

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

当前位置:首页 > 幼儿教育 > 少儿英语

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

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