
Android進(jìn)階筆記:bindService的流程--源碼解析
Android進(jìn)階筆記:bindService的流程–源碼解析
第?次寫博客,?的也是為了記錄??在Android學(xué)習(xí)過程中??發(fā)現(xiàn)的?些值得學(xué)習(xí)反復(fù)琢磨的東西也希望能和?家?起分享,如果寫的有什么不對的地?
還請?家多多指點(diǎn)。
?先想要知道bindService這?過程是怎么樣實(shí)現(xiàn)的,得先找到個(gè)路?,這個(gè)路?也很明顯,就是Activity中的bindService?法。代碼如下:
參數(shù)很簡單都很簡單,?過的應(yīng)該都了解。第?個(gè)參數(shù)就是?個(gè)啟動rvice的Intent?第?個(gè)參數(shù)是?個(gè)ServiceConnection的對象。這
個(gè)對象的實(shí)現(xiàn)?般需要實(shí)現(xiàn)兩個(gè)接?,如下所?:
實(shí)現(xiàn)的?法中會返回兩個(gè)參數(shù)?個(gè)是ComponentName另外?個(gè)是IBinder類型的實(shí)例。這個(gè)ComponentName其實(shí)就是記錄?個(gè)應(yīng)?的
包名已經(jīng)相關(guān)的組件名(例如:包名”ice”,組件名”ice”),?這個(gè)IBinder類型的對象就
是Service中OnBind?法中返回的Binder對象,如下:
具體這中間到底怎么實(shí)現(xiàn)的我們還是來看看源碼吧。Ctrl按住點(diǎn)擊bindService?法看到的代碼如下:
這?很清楚直接就就調(diào)?了Context的bindService那就直接點(diǎn)進(jìn)去唄。然后你會看到如下:
反正我???開看的時(shí)候就蒙了,這是?個(gè)abstract的?法,意思就是真正實(shí)現(xiàn)其實(shí)在他的?類。這這這。。這你讓我去哪?看怎么實(shí)現(xiàn)
bindService過程,還能不能看代碼了?
其實(shí),看到這?你應(yīng)該就要往回想想,這個(gè)?法是剛剛的mBa對象調(diào)?的,那這個(gè)mBa對象?定就是已經(jīng)實(shí)現(xiàn)了這個(gè)?法的?類對
象,那我們只要知道這個(gè)mBa到底是啥就可以看到這個(gè)bindService?法真正實(shí)現(xiàn)的過程了。這?直接給出答案這個(gè)mBa其實(shí)就是
ContextImpl類的對象,你要問我咋知道的。很簡單這個(gè)mBa既然是Activity對象的內(nèi)部成員,那只要了解Activity創(chuàng)建的過程肯定就知
道這是什么了。(具體想知道可以查查Activity創(chuàng)建啟動這塊的資料,當(dāng)然我以后也可能會寫的哈哈)。
bindService(rviceIntent,rviceConnection,_AUTO_CREATE);
ServiceConnectionrviceInatent=newServiceConnection(){
@Override
publicvoidonServiceConnected(ComponentNamename,IBinderrvice){
}
@Override
publicvoidonServiceDisconnected(ComponentNamename){
}
};
publicIBinderonBind(Intentintent){
returnnull;
}
publicclassContextWrapperextendsContext{
...
ContextmBa;
@Override
publicbooleanbindService(Intentrvice,ServiceConnectionconn,
intflags){
rvice(rvice,conn,flags);
}
...
}
publicabstractbooleanbindService(Intentrvice,@NonNullServiceConnectionconn,
@BindServiceFlagsintflags);
上?寫了這么多其實(shí)也是為了提供了?個(gè)看源碼的思路,當(dāng)然我也是可以直接就告訴你這個(gè)?法在哪實(shí)現(xiàn)。但是這樣就失去了?種過程感,
感覺就是在灌輸東西死記硬背。有?些東西你“知其所以然”以后印象肯定就?常的深了(這個(gè)也是寫給我??的“知其然并且知其所以
然”,這也是我開始看源碼的?的。我?忍不住廢話多了,騷瑞。。。)。
好了繼續(xù)上?的過程,既然我們知道這個(gè)bindService?法具體在哪個(gè)類??實(shí)現(xiàn)的我就直接去找到它點(diǎn)進(jìn)去看看就是了
位置:
這?已經(jīng)把?些不太重要的代碼省略了,?先進(jìn)?bindService?法,然后直接進(jìn)?了bindServiceCommon?法當(dāng)中。?這個(gè)
bindServiceCommon主要是實(shí)現(xiàn)了兩個(gè)步驟,第?個(gè)是實(shí)現(xiàn)了?個(gè)叫做IServiceConnection的對象,如果有看過?些源碼的應(yīng)該知道就
這尿性這命名多半是?個(gè)IBinder類的?類。這?我們先“存檔”?下,記住等下要回來的千萬別繞著繞著就忘記剛剛是從哪繞進(jìn)來
的了(這應(yīng)該也算是這個(gè)?法吧,源碼畢竟很多,很容易就看到后?忘記前?了)。
這??先我們要去看viceDispatcher這個(gè)?法,mPackageInfo這個(gè)很簡單(看?下聲明就知道了)是?個(gè)
LoadedApk類的實(shí)現(xiàn)對象,那么我們就去找到這個(gè)對象咯。
位置:
//bindService
@Override
publicbooleanbindService(Intentrvice,ServiceConnectionconn,intflags){
warnIfCallingFromSystemProcess();
returnbindServiceCommon(rvice,conn,flags,Handle());
}
//bindServiceCommon
privatebooleanbindServiceCommon(Intentrvice,ServiceConnectionconn,intflags,UrHandleur){
IServiceConnectionsd;
...
sd=viceDispatcher(conn,getOuterContext(),
dler(),flags);
...
intres=ault().bindService(
licationThread(),getActivityToken(),rvice,
eTypeIfNeeded(getContentResolver()),
sd,flags,getOpPackageName(),ntifier());
...
}
找到getServiceDispatcher?法可以看到其實(shí)上??坨都是判斷?下是不是空啊,是不是要創(chuàng)建?下啊,是不是要保存?下啦,都是浮
云。重要的是最后sd(eDispatcher)對象調(diào)?了getIServiceConnection()這個(gè)?法。那我們繼續(xù)跟蹤?下看看這個(gè)
?法的實(shí)現(xiàn)。
這個(gè)?法是屬于LoadedApk的?個(gè)內(nèi)部類ServiceDispatcher的?個(gè)?法,主要就是返回?個(gè)IServiceConnection類型的對象,那這個(gè)
IServiceConnection類型的對象到底是什么呢,我們就接下來看看ServiceDispatcher這個(gè)類到底是怎么樣的。
publicfinalIServiceConnectiongetServiceDispatcher(ServiceConnectionc,Contextcontext,Handlerhandler,intflags){
synchronized(mServices){
eDispatchersd=null;
ArrayMap
if(map!=null){
sd=(c);
}
if(sd==null){
sd=newServiceDispatcher(c,context,handler,flags);
if(map==null){
map=newArrayMap
(context,map);
}
(c,sd);
}el{
te(context,handler);
}
rviceConnection();
}
}
IServiceConnectiongetIServiceConnection(){
returnmIServiceConnection;
}
這?是?個(gè)很有有意思的地?,這個(gè)ServiceDispatcher是LoadedApk的內(nèi)部類,他內(nèi)部還有?個(gè)叫做InnerConnection的內(nèi)部類。看?
下聲明:
看聲明你就能發(fā)現(xiàn)很明顯?開始的getIServiceConnection()?法返回的就是這貨!這?是?個(gè)onnection類型
的實(shí)例,那我們要的是IServiceConnection類型的實(shí)例,那稍微想想就知道onnection肯定直接或者間接的繼
承了IServiceConnection。那我們就接著看看InnerConnection這個(gè)內(nèi)部類咯。
InnerConnection類他繼承的是?個(gè).stub類型的類(類其實(shí)?extend了IServiceConnection這個(gè)類),了解
過aidl的同學(xué)應(yīng)該明?這是什么(不懂的可以去學(xué)習(xí)?下AIDL的相關(guān)知識),這?說?了他就是?個(gè)IBinder類的?類主要是?來?持
IPC(跨進(jìn)程通信),說?話。。。就是?來跨進(jìn)程調(diào)??些?法。這個(gè)類總共只有兩個(gè)?法。
?先看這個(gè)類的第?個(gè)?法————構(gòu)造?法。
staticfinalclassServiceDispatcher{
onnectionmIServiceConnection;
privatefinalServiceConnectionmConnection;
privatefinalContextmContext;
privatefinalHandlermActivityThread;
privatefinalServiceConnectionLeakedmLocation;
privatefinalintmFlags;
ServiceDispatcher(ServiceConnectionconn,Contextcontext,HandleractivityThread,intflags){
mIServiceConnection=newInnerConnection(this);
mConnection=conn;
mContext=context;
mActivityThread=activityThread;
mLocation=newServiceConnectionLeaked(null);
StackTrace();
mFlags=flags;
}
{
finalWeakReference
InnerConnection(eDispatchersd){
mDispatcher=newWeakReference
}
publicvoidconnected(ComponentNamename,IBinderrvice)throwsRemoteException{
eDispatchersd=();
if(sd!=null){
ted(name,rvice);
}
}
}
IServiceConnectiongetIServiceConnection(){
returnmIServiceConnection;
}
...
}
onnectionmIServiceConnection;
...
IServiceConnectiongetIServiceConnection(){
returnmIServiceConnection;
}
他引?(弱引?)了?個(gè)他的上級類(ServiceDispatcher)的實(shí)例并且保存下來了。這?注意,InnerConnection內(nèi)部類他引?了他的
上級類的實(shí)例,也就是說InnerConnection可以通過ServiceDispatcher實(shí)例來調(diào)?ServiceDispatcher類中的公有?
法,InnerConnection?是?個(gè)?持跨進(jìn)程的類,也就是說InnerConnection可以實(shí)現(xiàn)跨進(jìn)程來調(diào)?ServiceDispatcher和
InnerConnection這兩個(gè)類中的所有公有?法,形象的說就是?個(gè)橋梁來連接兩個(gè)進(jìn)程之間?法的調(diào)?,這?也是我覺得他很有意思的原
因。
說完了構(gòu)造?法,那我們再去看看另外?個(gè)?法connected(ComponentNamename,IBinderrvice)
瞅瞅?法名,再瞅瞅參數(shù),怎么就那么眼熟呢?沒錯(cuò),這個(gè)?法其實(shí)就是對我們之前ServiceConnection類中onServiceConnected?法的
封裝,最后還是會調(diào)?到iceConnected這個(gè)?法的,不信再跟蹤?下源碼看看:
很明顯吧這個(gè)mConnection其實(shí)就是?開始ServiceDispatcher的構(gòu)造函數(shù)中傳進(jìn)來的ServiceConnection實(shí)例,看?下他的聲明就明?
了。最后就是調(diào)?了iceConnected(name,rvice)這個(gè)?法。這個(gè)地?要有?點(diǎn)印象,因?yàn)楹?會通過
InnerConnection實(shí)例來遠(yuǎn)程回調(diào)這個(gè)?法。
分析完ServiceDispatcher這個(gè)類以及他的內(nèi)部類InnerConnection,也可以稍微的總結(jié)?下。
我們?開始時(shí)為了獲得?個(gè)IServiceConnection類的實(shí)例,?這個(gè)類的實(shí)例是通過rviceConnection()?法獲得
的,這個(gè)?法?調(diào)?了他的內(nèi)部類eDispatcher的InnerConnection實(shí)例,這個(gè)實(shí)例通過?系列的繼承最后?類就是
IServiceConnection;是不是有點(diǎn)暈。。。。稍微畫?下這三個(gè)類的關(guān)系結(jié)構(gòu)
InnerConnection(eDispatchersd){
mDispatcher=newWeakReference
}
publicvoidconnected(ComponentNamename,IBinderrvice)throwsRemoteException{
eDispatchersd=();
if(sd!=null){
ted(name,rvice);
}
}
//ted
publicvoidconnected(ComponentNamename,IBinderrvice){
if(mActivityThread!=null){
(newRunConnection(name,rvice,0));
}el{
doConnected(name,rvice);
}
}
//ected
publicvoiddoConnected(ComponentNamename,IBinderrvice){
...
//Ifthereisanewrvice,itisnowconnected.
if(rvice!=null){
iceConnected(name,rvice);
}
}
這下這三個(gè)類的關(guān)系應(yīng)該很明確了吧。最后拿到的其實(shí)就是InnerConnection這東西。
好了休息?下,還記得前?我有說存檔?下嗎?現(xiàn)在我們也該回到前?說的“存檔”點(diǎn)了,可別繞暈了啊。
上?我們分析了這個(gè)sd到底是什么東西(有遠(yuǎn)程調(diào)?功能的?個(gè)東西),有什么?(保存數(shù)據(jù),實(shí)現(xiàn)連接??的?法,遠(yuǎn)程調(diào)?)。那么我
們就繼續(xù)來分析接下來的?塊:
其實(shí)就調(diào)?了?個(gè)?法ault().bindService()剩下的那?坨都是參數(shù),要知道?下的是第?個(gè)參數(shù)其實(shí)是?
個(gè)ApplicationThread類型的實(shí)例,他是AtivityThread的內(nèi)部類,?ApplicationThread繼承了IApplicationThread也是?個(gè)IBinder類
型實(shí)例,也就是說我們可以運(yùn)?它來遠(yuǎn)程的調(diào)?ApplicationThread類中的?法。還有別忘記剛剛我們拿到的sd也跟著傳進(jìn)去了,?于那個(gè)
rvice其實(shí)是?個(gè)intent。
那問題來了ault()到底是?個(gè)什么東西呢?其實(shí)這是?個(gè)ActivityManagerService的Binder驅(qū)動,也是?
個(gè)IBinder類型的對象。主要是通過這個(gè)Binder驅(qū)動來跨進(jìn)程調(diào)?ActivityManagerService中的?法,這?就是調(diào)?了
rvice?法。
這?我還是給出了ActivityManagerNative類的位置吧。
位置:
那我們就繼續(xù)去看看rvice這個(gè)?法。
位置:platformframewo
很簡單沒什么好說的就是調(diào)?了ActiveServices中的bindServiceLocked這個(gè)?法。
位置:platfor
publicfinalclassLoadedApk{
staticfinalclassServiceDispatcher{
{
//tendIServiceConnection
finalWeakReference
}
}
}
sd=viceDispatcher(conn,getOuterContext(),
dler(),flags);
intres=ault().bindService(
licationThread(),getActivityToken(),rvice,
eTypeIfNeeded(getContentResolver()),
sd,flags,getOpPackageName(),ntifier());
publicintbindService(IApplicationThreadcaller,IBindertoken,Intentrvice,StringresolvedType,IServiceConnectionconnection,intflags,Strin
inturId)throwsTransactionTooLargeException{
...
synchronized(this){
rviceLocked(caller,token,rvice,
resolvedType,connection,flags,callingPackage,urId);
}
}
這?我做了刪減,這個(gè)代碼其實(shí)耐?的看?下還是很清晰的就是s(ServiceRecord)、b(AppBindRecord)、
c(ConnectionRecord)、callerApp(ProcessRecord)這四個(gè)類型的?些保存啊之類的操作,?便以后調(diào)?。可以觀察?下這三個(gè)
類的命名,都很有規(guī)則都是有?個(gè)Record后綴,其實(shí)就?個(gè)對應(yīng)的描述類保存了后?要?到的信息(如:ServiceRecord,這??就存放
了將來要創(chuàng)建Service時(shí)所需要的所有信息)
這?還是要說明?下ServiceRecord是對Service(需要綁定的Service)信息存放,c是對?開始我們傳進(jìn)來的IServiceConnection封
裝,各種地?都保存了這個(gè)c?便調(diào)?。
intbindServiceLocked(IApplicationThreadcaller,IBindertoken,Intentrvice,
StringresolvedType,IServiceConnectionconnection,intflags,
StringcallingPackage,inturId)throwsTransactionTooLargeException{
finalProcessRecordcallerApp=ordForAppLocked(caller);
ActivityRecordactivity=null;
if(token!=null){
activity=ackLocked(token);
}
ServiceLookupResultres=
retrieveServiceLocked(rvice,resolvedType,callingPackage,
lingPid(),lingUid(),urId,true,callerFg);
ServiceRecords=;
try{
AppBindRecordb=veAppBindingLocked(rvice,callerApp);
ConnectionRecordc=newConnectionRecord(b,activity,
connection,flags,clientLabel,clientIntent);
IBinderbinder=er();
ArrayList
if(clist==null){
clist=newArrayList
(binder,clist);
}
(c);
(c);
if(activity!=null){
...
(c);
}
(c);
if((flags&_AUTO_CREATE)!=0){
tivity=Millis();
if(bringUpServiceLocked(s,gs(),callerFg,fal)!=null){
return0;
}
}
...
return1;
}
IBinderbinder=er();
?這個(gè)binder其實(shí)可以簡單的看做成IServiceConnection,后?可以通過它asInterface?法獲取binder驅(qū)動來遠(yuǎn)程調(diào)?
IServiceConnection(其實(shí)就是IServiceConnection–>InnerConnection–>ServiceDispatcher)??的?法。然后把這個(gè)binder放
到了s(ServiceRecord)的connections的集合中,clist就是?個(gè)connectionRecord的集合,應(yīng)為可能不??個(gè)activity或者組件需要綁
定這個(gè)rvice。
接下來我們根據(jù)設(shè)置的flag(?般都是設(shè)置成這個(gè))會進(jìn)?到if語句塊,然后調(diào)?bringUpServiceLocked這個(gè)?法
這?很明確既然調(diào)?了那我們繼續(xù)動?點(diǎn)進(jìn)去看看唄。
這塊代碼源碼那邊其實(shí)稍微有點(diǎn)多,但是?多是都是進(jìn)??些空值或者變量的判斷,?些重要的變量如果異常則直接返回不再執(zhí)?。如果正
常則會執(zhí)?到如上所?的?法。
r就是ServiceRecord剛剛bindServiceLocked?法中封裝了的對rvice的描述實(shí)例(?來創(chuàng)建rvice可以簡單的理解就是?個(gè)不成
型的rvice)。
app就是剛剛提到的processRecord變量,剛剛也提到過是?來存儲?些數(shù)據(jù)(其實(shí)也就是當(dāng)前應(yīng)?相關(guān)的數(shù)據(jù))。
mAm就是ActivityManagerService的實(shí)例
然后最后會執(zhí)?到realStartServiceLocked,看名字real,說明這?是真正的開始啟動?個(gè)Service的地?,那就繼續(xù)點(diǎn)進(jìn)去看看咯。
(binder,clist);
if((flags&_AUTO_CREATE)!=0){
tivity=Millis();
if(bringUpServiceLocked(s,gs(),callerFg,fal)!=null){
return0;
}
}
privatefinalStringbringUpServiceLocked(ServiceRecordr,intintentFlags,booleanexecInFg,booleanwhileRestarting)throwsTransactionTooL
...
if(!isolated){
app=cessRecordLocked(procName,,fal);
if(DEBUG_MU)Slog.v(TAG_MU,"bringUpServiceLocked:="+
+"app="+app);
if(app!=null&&!=null){
try{
kage(eName,nCode,ssStats);
realStartServiceLocked(r,app,execInFg);
returnnull;
}catch(TransactionTooLargeExceptione){
throwe;
}catch(RemoteExceptione){
Slog.w(TAG,"Exceptionwhenstartingrvice"+ame,e);
}
//Ifadeadobjectexceptionwasthrown--fallthroughto
//restarttheapplication.
}
}
...
returnnull;
}
上?app就是之前傳過來的,?這個(gè)到底是什么呢,我們?nèi)rocessRecord類??去看看。
其實(shí)就是之前說到的ApplicationThread的遠(yuǎn)程接?IApplicationThread,就是說可以跨進(jìn)程的通過它來調(diào)?ApplicationThread??的
?法。
既然這樣IApplicationThread調(diào)?了scheduleCreateService這個(gè)?法,看名字就知道是打算真正的來創(chuàng)建這個(gè)Service了。那很簡單我
們只要直接去ActivityThread類(ApplicationThread是ActivityThread的內(nèi)部類所以別找錯(cuò)地?哦)??去找就?了。
這個(gè)?法全部也只有這??很?,主要做的?作就是發(fā)送?個(gè)消息并且通過token和info來創(chuàng)建了?個(gè)新的ServiceRecord(真正的東西其
實(shí)都在toke和info??,這?之所以他們能被跨進(jìn)程傳過來其實(shí)是因?yàn)閠oke是Ibinder類型?info實(shí)現(xiàn)了parcelable接?)傳遞給
H(ActivityThread內(nèi)部的?個(gè)Handler)處理來創(chuàng)建?個(gè)Service。那我們就繼續(xù)去找這個(gè)Handler他收到消息具體去?什么了。
privatefinalvoidrealStartServiceLocked(ServiceRecordr,
ProcessRecordapp,booleanexecInFg)throwsRemoteException{
...
=app;
...
leCreateService(r,eInfo,
ibilityInfoForPackageLocked(ationInfo),
cState);
tification();
...
requestServiceBindingsLocked(r,execInFg);
updateServiceClientActivitiesLocked(app,null,true);
...
}
finalclassProcessRecord{
...
IApplicationThreadthread;//theactualproc...maybenullonlyif
//'persistent'istrue(inwhichcawe
//areintheprocessoflaunchingtheapp)
...
}
publicfinalvoidscheduleCreateService(IBindertoken,
ServiceInfoinfo,CompatibilityInfocompatInfo,intprocessState){
updateProcessState(processState,fal);
CreateServiceDatas=newCreateServiceData();
=token;
=info;
Info=compatInfo;
ndMessage(_SERVICE,s);
}
這?也很簡單發(fā)送消息給Handler,讓handerMessage?法來處理消息,然后回調(diào)了handleCreateService這個(gè)?法。這個(gè)?法??就開
始真正的創(chuàng)建了?個(gè)Service實(shí)例。data其實(shí)就是ServiceRecord。到這?步?個(gè)rvice的創(chuàng)建算是完成了。但是我們要做的事情還沒完
啊!我們討論的是bindService。回過去看看,我們之前是從leCreateService?法?路?到rvice的創(chuàng)建,那么下?
其實(shí)還有?個(gè)?法沒有完成,就是requestServiceBindingsLocked。
//Handler的回調(diào)函數(shù)handleMessage
publicvoidhandleMessage(Messagemsg){
switch(){
...
caCREATE_SERVICE:
egin(_TAG_ACTIVITY_MANAGER,"rviceCreate");
handleCreateService((CreateServiceData));
nd(_TAG_ACTIVITY_MANAGER);
...
}
}
//Hander通過handlerMessage回調(diào)的?法
privatevoidhandleCreateService(CreateServiceDatadata){
LoadedApkpackageInfo=getPackageInfoNoCheck(
ationInfo,Info);
Servicervice=null;
...
oadercl=ssLoader();
rvice=(Service)ass().newInstance();
Applicationapp=plication(fal,mInstrumentation);
(context,this,,,app,
ault());
//te真正回調(diào)的地?
te();
(,rvice);
...
}
privatefinalvoidrealStartServiceLocked(ServiceRecordr,
ProcessRecordapp,booleanexecInFg)throwsRemoteException{
...
=app;
...
leCreateService(r,eInfo,
ibilityInfoForPackageLocked(ationInfo),
cState);
tification();
...
//就是這個(gè)?法
requestServiceBindingsLocked(r,execInFg);
updateServiceClientActivitiesLocked(app,null,true);
...
}
看名字就知道是請求綁定rvice,那就繼續(xù)唄。離勝利不遠(yuǎn)了!
這?就很簡單了,就是調(diào)?了?下requestServiceBindingLocked。這?為什么弄個(gè)循環(huán)去做這件事情呢,我想也是應(yīng)為?個(gè)Service可能
會被多個(gè)Activity去綁定所以需要?個(gè)循環(huán)來處理(具體還沒研究過)。
看看?法??怎么實(shí)現(xiàn)的。其實(shí)還是那個(gè)尿性,就是把需要的東西全部都通過binder驅(qū)動來遠(yuǎn)程傳給
ActivtyThread(ApplicationThread)的scheduleBindService?法去實(shí)現(xiàn)那么?樣?這?直接去找?下這個(gè)?法是怎么實(shí)現(xiàn)的就好了。
沒錯(cuò)!?套路,還是發(fā)消息,這?我就不具體貼代碼了最后通過handlerMessage?法來調(diào)?handleBindService?法,參數(shù)也仍然是
ServiceRecord對象,這?我們就直接看看這個(gè)?法吧。
這?因?yàn)橹癝ervice已經(jīng)創(chuàng)建過了并且保存在了mServices這個(gè)集合??了
privatefinalvoidrequestServiceBindingsLocked(ServiceRecordr,booleanexecInFg)
throwsTransactionTooLargeException{
for(inti=()-1;i>=0;i--){
IntentBindRecordibr=t(i);
if(!requestServiceBindingLocked(r,ibr,execInFg,fal)){
break;
}
}
}
privatefinalbooleanrequestServiceBindingLocked(ServiceRecordr,IntentBindRecordi,
booleanexecInFg,booleanrebind)throwsTransactionTooLargeException{
...
leBindService(r,ent(),rebind,
cState);
...
returntrue;
}
publicfinalvoidscheduleBindService(IBindertoken,Intentintent,
booleanrebind,intprocessState){
updateProcessState(processState,fal);
BindServiceDatas=newBindServiceData();
=token;
=intent;
=rebind;
if(DEBUG_SERVICE)
Slog.v(TAG,"scheduleBindServicetoken="+token+"intent="+intent+"uid="
+lingUid()+"pid="+lingPid());
ndMessage(_SERVICE,s);
}
privatevoidhandleBindService(BindServiceDatadata){
Services=();
...
if(!){
IBinderbinder=();
ault().publishService(
,,binder);
}
...
}
所以直接取出來了就可以了。好了,回過頭然后?法??通過調(diào)?Service的onBind?法來獲得?個(gè)binder對象,這個(gè)?法只要繼承了
Service并且要實(shí)現(xiàn)綁定的話是肯定要重寫的,這??返回的Binder對象是??傳?的可以是null。最后?是通過
ault()(之前也解釋過,這個(gè)其實(shí)就是?個(gè)ActivityManagerService的遠(yuǎn)程驅(qū)動)來調(diào)?publishService
這個(gè)?法,那我們就再回去,在去ActivityManagerService??找這個(gè)?法;
沒什么營養(yǎng),反正就是各種異常判斷?下最后調(diào)?了mServices(ActiveServices類的實(shí)例)的publishServiceLocked?法。
這?就是從ServiceRecord??取出了ConnectionRecord然后調(diào)?了ted(,rvice);這么?個(gè)?法。?于細(xì)?的
同學(xué)應(yīng)該想起來之前bindServiceLocked??創(chuàng)建完ServiceRecord的時(shí)候有這么?段代碼
沒錯(cuò),這個(gè)ConnectionRecord就是那時(shí)候存進(jìn)去的。
privatevoidhandleCreateService(CreateServiceDatadata){
...
(,rvice);
...
}
publicvoidpublishService(IBindertoken,Intentintent,IBinderrvice){
//Refupossibleleakedfiledescriptors
if(intent!=null&&eDescriptors()==true){
thrownewIllegalArgumentException("FiledescriptorspasdinIntent");
}
synchronized(this){
if(!(tokeninstanceofServiceRecord)){
thrownewIllegalArgumentException("Invalidrvicetoken");
}
hServiceLocked((ServiceRecord)token,intent,rvice);
}
}
voidpublishServiceLocked(ServiceRecordr,Intentintent,IBinderrvice){
...
for(intconni=()-1;conni>=0;conni--){
ArrayList
for(inti=0;i<();i++){
ConnectionRecordc=(i);
...
try{
ted(,rvice);
}catch(Exceptione){
Slog.w(TAG,"Failurendingrvice"++
"toconnection"+er()+
"(in"+sName+")",e);
}
}
}
...
}
if(clist==null){
clist=newArrayList
(binder,clist);
}
ted(,rvice)這個(gè)?法??的rvice就是剛剛創(chuàng)建的(我們??從來的?法)返回回來的binder
對象,?這個(gè)其實(shí)是?個(gè)ComponentName的對象。怎么樣,是不是感覺這個(gè)?法的參數(shù)有?點(diǎn)熟悉啊!這不就是
ServiceConnection對象??的onServiceConnected(ComponentNamename,IBinderrvice)?法要的參數(shù)嘛。那這個(gè)?法百分之
??就是輾轉(zhuǎn)調(diào)?到了這個(gè)?法咯。那我們就去看看這個(gè)到底是什么
看吧,這就是我之前說的那個(gè)Inn什么的記起來了嘛(InnerConnection),我之前也提到過“最后就是調(diào)?了
iceConnected(name,rvice)這個(gè)?法。這個(gè)地?要有?點(diǎn)印象,因?yàn)楹?會通過InnerConnection實(shí)例來遠(yuǎn)程
回調(diào)這個(gè)?法。”忘記在哪個(gè)步驟的可以ctrl+f搜?下這句話回過去再看看。
到上?的步驟其實(shí)bindService的流程已經(jīng)分析的差不多了,可能有?些多,凡是思路還是很清晰的。
總結(jié)?下其實(shí)就是把?些真正需要創(chuàng)建Service要?的東西全部都給ActivityManagerService來做(跨進(jìn)程)然后做完了在丟給
ActivityThread(ApplicationThread)去真正的創(chuàng)建。
從上?的源碼其實(shí)也可以看出iceConnected這個(gè)回調(diào)是通過跨進(jìn)程來調(diào)?的,?最后通過
IServiceConnection來調(diào)?connected?法(這個(gè)?法真正回調(diào)了onServiceConnected?法)
?connected?法所在的類的實(shí)例是創(chuàng)建在UI線程的
finalclassConnectionRecord{
...
finalIServiceConnectionconn;//Theclientconnection.
...
}
因此onServiceConnected這個(gè)?法其實(shí)是運(yùn)?在主線程中的,如果Server端的?法是耗時(shí)操作最好起?個(gè)線程來調(diào)?,因?yàn)樵谡{(diào)?
IBinder的transact?法時(shí)當(dāng)前線程是會掛起的!
第?次寫博客可能有點(diǎn)亂,這之中也花了好多時(shí)間,不管怎么樣寫出來了也?便以后??查看。省的我那天腦??抽?忘記了。
//
sd=viceDispatcher(conn,getOuterContext(),
dler(),flags);
publicfinalIServiceConnectiongetServiceDispatcher(ServiceConnectionc,
Contextcontext,Handlerhandler,intflags){
...
sd=newServiceDispatcher(c,context,handler,flags);
...
}
ServiceDispatcher(ServiceConnectionconn,Contextcontext,HandleractivityThread,intflags){
mIServiceConnection=newInnerConnection(this);
...
}
{
...
publicvoidconnected(ComponentNamename,IBinderrvice)throwsRemoteException{
eDispatchersd=();
if(sd!=null){
ted(name,rvice);
}
}
}
publicvoidconnected(ComponentNamename,IBinderrvice){
if(mActivityThread!=null){
(newRunConnection(name,rvice,0));
}el{
doConnected(name,rvice);
}
}
publicvoiddoConnected(ComponentNamename,IBinderrvice){
...
//Ifthereisanewrvice,itisnowconnected.
if(rvice!=null){
iceConnected(name,rvice);
}
}
本文發(fā)布于:2023-03-12 05:02:51,感謝您對本站的認(rèn)可!
本文鏈接:http://www.newhan.cn/zhishi/a/1678568572138087.html
版權(quán)聲明:本站內(nèi)容均來自互聯(lián)網(wǎng),僅供演示用,請勿用于商業(yè)和其他非法用途。如果侵犯了您的權(quán)益請與我們聯(lián)系,我們將在24小時(shí)內(nèi)刪除。
本文word下載地址:尿性是什么意思.doc
本文 PDF 下載地址:尿性是什么意思.pdf
| 留言與評論(共有 0 條評論) |