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取出与其映射的ServiceDispatcher对象,最后调用这个ServiceDispatcher对象的getIServiceConnection方法获取与其关联的InnerConnection对象并返回。
简单点理解就是用ServiceConnection换来了InnerConnection。
现在回到bindServiceCommon方法,可以看到绑定Service的过程会转到ActivityManagerNative.getDefault()的bindService方法,其实从抛出的异常类型RemoteException也可以知道与Service通信可能是跨进程的,这个是很好理解的。
而ActivityManagerNative.getDefault()是ActivityManagerService,那么继续跟进ActivityManagerService的bindService方法即可,如下:
publicintbindService(IApplicationThreadcaller,IBindertoken,Intentservice,
StringresolvedType,IServiceConnectionconnection,intflags,StringcallingPackage,
intuserId)throwsTransactionTooLargeException{
enforceNotIsolatedCaller("bindService");
//Refusepossibleleakedfiledescriptors
if(service!
=null&&service.hasFileDescriptors()==true){
thrownewIllegalArgumentException("FiledescriptorspassedinIntent");
}
if(callingPackage==null){
thrownewIllegalArgumentException("callingPackagecannotbenull");
}
synchronized(this){
returnmServices.bindServiceLocked(caller,token,service,
resolvedType,connection,flags,callingPackage,userId);
}
}
在上述代码中,绑定Service的过程转到ActiveServices的bindServiceLocked方法,那就跟进ActiveServices的bindServiceLocked方法瞧瞧。
如下:
intbindServiceLocked(IApplicationThreadcaller,IBindertoken,Intentservice,
StringresolvedType,finalIServiceConnectionconnection,intflags,
StringcallingPackage,finalintuserId)throwsTransactionTooLargeException{
//代码省略
ConnectionRecordc=newConnectionRecord(b,activity,
connection,flags,clientLabel,clientIntent);
IBinderbinder=connection.asBinder();
ArrayListclist=s.connections.get(binder);
if(clist==null){
clist=newArrayList();
s.connections.put(binder,clist);
}
clist.add(c);
//代码省略
if((flags&Context.BIND_AUTO_CREATE)!
=0){
s.lastActivity=SystemClock.uptimeMillis();
if(bringUpServiceLocked(s,service.getFlags(),callerFg,false,
permissionsReviewRequired)!
=null){
return0;
}
}
//代码省略
return1;
}
将connection对象封装在ConnectionRecord中,这里的connection就是上面提到的InnerConnection对象。
这一步很重要的。
然后调用了bringUpServiceLocked方法,那么就探探这个bringUpServiceLocked方法,
privateStringbringUpServiceLocked(ServiceRecordr,intintentFlags,booleanexecInFg,
booleanwhileRestarting,booleanpermissionsReviewRequired)
throwsTransactionTooLargeException{
//代码省略
if(app!
=null&&app.thread!
=null){
try{
app.addPackage(r.appInfo.packageName,r.appInfo.versionCode,mAm.mProcessStats);
realStartServiceLocked(r,app,execInFg);
returnnull;
}catch(TransactionTooLargeExceptione){
throwe;
}catch(RemoteExceptione){
Slog.w(TAG,"Exceptionwhenstartingservice"+r.shortName,e);
}
//Ifadeadobjectexceptionwasthrown--fallthroughto
//restarttheapplication.
}
//代码省略
returnnull;
}
可以看到调用了realStartServiceLocked方法,真正去启动Service了。
那么跟进realStartServiceLocked方法探探,如下:
privatefinalvoidrealStartServiceLocked(ServiceRecordr,
ProcessRecordapp,booleanexecInFg)throwsRemoteException{
//代码省略
app.thread.scheduleCreateService(r,r.serviceInfo,
mApatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
app.repProcState);
r.postNotification();
created=true;
//代码省略
requestServiceBindingsLocked(r,execInFg);
updateServiceClientActivitiesLocked(app,null,true);
//Iftheserviceisinthestartedstate,andthereareno
//pendingarguments,thenfakeuponesoitsonStartCommand()will
//becalled.
if(r.startRequested&&r.callStart&&r.pendingStarts.size()==0){
r.pendingStarts.add(newServiceRecord.StartItem(r,false,r.makeNextStartId(),
null,null));
}
sendServiceArgsLocked(r,execInFg,true);
//代码省略
}
这里会调用app.thread的scheduleCreateService方法去创建一个Service,然后会回调Service的生命周期方法,然而绑定Service呢?
在上述代码中,找到一个requestServiceBindingsLocked方法,从名字看是请求绑定服务的意思,那么就是它没错了。
privatefinalvoidrequestServiceBindingsLocked(ServiceRecordr,booleanexecInFg)
throwsTransactionTooLargeException{
for(inti=r.bindings.size()-1;i>=0;i--){
IntentBindRecordibr=r.bindings.valueAt(i);
if(!
requestServiceBindingLocked(r,ibr,execInFg,false)){
break;
}
}
}
咦,我再按住Ctrl+鼠标左键,点进去requestServiceBindingLocked方法。
如下:
privatefinalbooleanrequestServiceBindingLocked(ServiceRecordr,IntentBindRecordi,
booleanexecInFg,booleanrebind)throwsTransactionTooLargeException{
if(r.app==null||r.app.thread==null){
//Ifserviceisnotcurrentlyrunning,can'tyetbind.
returnfalse;
}
if((!
i.requested||rebind)&&i.apps.size()>0){
try{
bumpServiceExecutingLocked(r,execInFg,"bind");
r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
r.app.thread.scheduleBindService(r,i.intent.getIntent(),rebind,
r.app.repProcState);
if(!
rebind){
i.requested=true;
}
i.hasBound=true;
i.doRebind=false;
}
//代码省略
returntrue;
}
r.app.thread调用了scheduleBindService方法来绑定服务,而r.app.thread是Applicat