日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

android服务的启动过程,Android Service的启动过程(上)

發(fā)布時間:2025/3/20 Android 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android服务的启动过程,Android Service的启动过程(上) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

原標題:Android Service的啟動過程(上)

(點擊上方公眾號,可快速關注)

來源:伯樂在線專欄作者 - xuyinhuan

鏈接:http://android.jobbole.com/85150/

剛開始學習Service的時候以為它是一個線程的封裝,也可以執(zhí)行耗時操作。其實不然,Service是運行在主線程的。直接執(zhí)行耗時操作是會阻塞主線程的。長時間就直接ANR了。

我們知道Service可以執(zhí)行一些后臺任務,是后臺任務不是耗時的任務,后臺和耗時是有區(qū)別的喔。

這樣就很容易想到音樂播放器,天氣預報這些應用是要用到Service的。當然如果要在Service中執(zhí)行耗時操作的話,開個線程就可以了。

關于Service的運行狀態(tài)有兩種,啟動狀態(tài)和綁定狀態(tài),兩種狀態(tài)可以一起。

啟動一個Service只需調用Context的startService方法,傳進一個Intent即可。看起來好像很簡單的說,那是因為Android為了方便開發(fā)者,做了很大程度的封裝。那么你真的有去學習過Service是怎么啟動的嗎?Service的onCreate方法回調前都做了哪些準備工作?

先上一張圖大致了解下,灰色背景框起來的是同一個類中的方法,如下圖:

那接下來就從源碼的角度來分析Service的啟動過程。

當然是從Context的startService方法開始,Context的實現(xiàn)類是ContextImpl,那么我們就看到ContextImpl的startService方法即可,如下:

@Override

publicComponentName startService(Intentservice){

warnIfCallingFromSystemProcess();

returnstartServiceCommon(service,mUser);

}

會轉到startServiceCommon方法,那跟進startServiceCommon方法方法瞧瞧。

privateComponentName startServiceCommon(Intentservice,UserHandleuser){

try{

validateServiceIntent(service);

service.prepareToLeaveProcess();

ComponentNamecn=ActivityManagerNative.getDefault().startService(

mMainThread.getApplicationThread(),service,service.resolveTypeIfNeeded(

getContentResolver()),getOpPackageName(),user.getIdentifier());

//代碼省略

returncn;

}catch(RemoteExceptione){

thrownewRuntimeException("Failure from system",e);

}

}

可以看到調用了ActivityManagerNative.getDefault()的startService方法來啟動Service,ActivityManagerNative.getDefault()是ActivityManagerService,簡稱AMS。

那么現(xiàn)在啟動Service的過程就轉移到了ActivityManagerService,我們關注ActivityManagerService的startService方法即可,如下:

@Override

publicComponentName startService(IApplicationThreadcaller,Intentservice,

StringresolvedType,StringcallingPackage,intuserId)

throwsTransactionTooLargeException{

//代碼省略

synchronized(this){

finalintcallingPid=Binder.getCallingPid();

finalintcallingUid=Binder.getCallingUid();

finallongorigId=Binder.clearCallingIdentity();

ComponentNameres=mServices.startServiceLocked(caller,service,

resolvedType,callingPid,callingUid,callingPackage,userId);

Binder.restoreCallingIdentity(origId);

returnres;

}

}

在上述的代碼中,調用了ActiveServices的startServiceLocked方法,那么現(xiàn)在Service的啟動過程從AMS轉移到了ActiveServices了。

繼續(xù)跟進ActiveServices的startServiceLocked方法,如下:

ComponentName startServiceLocked(IApplicationThreadcaller,Intentservice,StringresolvedType,

intcallingPid,intcallingUid,StringcallingPackage,intuserId)

throwsTransactionTooLargeException{

//代碼省略

ServiceLookupResultres=

retrieveServiceLocked(service,resolvedType,callingPackage,

callingPid,callingUid,userId,true,callerFg);

//代碼省略

ServiceRecordr=res.record;

//代碼省略

returnstartServiceInnerLocked(smap,service,r,callerFg,addToStarting);

}

在startServiceLocked方法中又會調用startServiceInnerLocked方法,

我們瞧瞧startServiceInnerLocked方法,

ComponentName startServiceInnerLocked(ServiceMapsmap,Intentservice,ServiceRecordr,

booleancallerFg,booleanaddToStarting)throwsTransactionTooLargeException{

ProcessStats.ServiceStatestracker=r.getTracker();

if(stracker!=null){

stracker.setStarted(true,mAm.mProcessStats.getMemFactorLocked(),r.lastActivity);

}

r.callStart=false;

synchronized(r.stats.getBatteryStats()){

r.stats.startRunningLocked();

}

Stringerror=bringUpServiceLocked(r,service.getFlags(),callerFg,false);

//代碼省略

returnr.name;

}

startServiceInnerLocked方法內部調用了bringUpServiceLocked方法,此時啟動過程已經(jīng)快要離開ActiveServices了。繼續(xù)看到bringUpServiceLocked方法。如下:

privatefinalStringbringUpServiceLocked(ServiceRecordr,intintentFlags,booleanexecInFg,

booleanwhileRestarting)throwsTransactionTooLargeException{

//代碼省略

if(app!=null&&app.thread!=null){

try{

app.addPackage(r.appInfo.packageName,r.appInfo.versionCode,mAm.mProcessStats);

realStartServiceLocked(r,app,execInFg);

returnnull;

}

//代碼省略

returnnull;

}

省略了大部分if判斷,相信眼尖的你一定發(fā)現(xiàn)了核心的方法,那就是

realStartServiceLocked,沒錯,看名字就像是真正啟動Service。那么事不宜遲跟進去探探吧。如下:

privatefinalvoidrealStartServiceLocked(ServiceRecordr,

ProcessRecordapp,booleanexecInFg)throwsRemoteException{

//代碼省略

booleancreated=false;

try{

//代碼省略

app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);

app.thread.scheduleCreateService(r,r.serviceInfo,

mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),

app.repProcState);

r.postNotification();

created=true;

}catch(DeadObjectExceptione){

Slog.w(TAG,"Application dead when creating service "+r);

mAm.appDiedLocked(app);

throwe;

}

//代碼省略

sendServiceArgsLocked(r,execInFg,true);

//代碼省略

}

找到了。app.thread調用了scheduleCreateService來啟動Service,而app.thread是一個ApplicationThread,也是ActivityThread的內部類。此時已經(jīng)到了主線程。

那么我們探探ApplicationThread的scheduleCreateService方法。如下:

publicfinalvoidscheduleCreateService(IBindertoken,

ServiceInfoinfo,CompatibilityInfocompatInfo,intprocessState){

updateProcessState(processState,false);

CreateServiceDatas=newCreateServiceData();

s.token=token;

s.info=info;

s.compatInfo=compatInfo;

sendMessage(H.CREATE_SERVICE,s);

}

對待啟動的Service組件信息進行包裝,然后發(fā)送了一個消息。我們關注這個CREATE_SERVICE消息即可。

publicvoidhandleMessage(Messagemsg){

//代碼省略

caseCREATE_SERVICE:

Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,"serviceCreate");

handleCreateService((CreateServiceData)msg.obj);

Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

break;

//代碼省略

}

在handleMessage方法中接收到這個消息,然后調用了handleCreateService方法,跟進handleCreateService探探究竟:

privatevoidhandleCreateService(CreateServiceDatadata){

// If we are getting ready to gc after going to the background, well

// we are back active so skip it.

unscheduleGcIdler();

LoadedApkpackageInfo=getPackageInfoNoCheck(

data.info.applicationInfo,data.compatInfo);

Serviceservice=null;

try{

java.lang.ClassLoadercl=packageInfo.getClassLoader();

service=(Service)cl.loadClass(data.info.name).newInstance();

}catch(Exceptione){

if(!mInstrumentation.onException(service,e)){

thrownewRuntimeException(

"Unable to instantiate service "+data.info.name

+": "+e.toString(),e);

}

}

try{

if(localLOGV)Slog.v(TAG,"Creating service "+data.info.name);

ContextImplcontext=ContextImpl.createAppContext(this,packageInfo);

context.setOuterContext(service);

Applicationapp=packageInfo.makeApplication(false,mInstrumentation);

service.attach(context,this,data.info.name,data.token,app,

ActivityManagerNative.getDefault());

service.onCreate();

mServices.put(data.token,service);

try{

ActivityManagerNative.getDefault().serviceDoneExecuting(

data.token,SERVICE_DONE_EXECUTING_ANON,0,0);

}catch(RemoteExceptione){

// nothing to do.

}

}catch(Exceptione){

if(!mInstrumentation.onException(service,e)){

thrownewRuntimeException(

"Unable to create service "+data.info.name

+": "+e.toString(),e);

}

}

}

終于擊破,這個方法很核心的。一點點分析

接下文

關注「安卓開發(fā)精選」

看更多精選安卓技術文章

責任編輯:

總結

以上是生活随笔為你收集整理的android服务的启动过程,Android Service的启动过程(上)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。