Service的启动流程——基于Android11
Service的启动流程——基于Android11
最近在重温Android系统的相关知识点,我们都知道Android有四⼤组件,Activity、Service、Broadcast Receive、Content Provider,像对⽐其他知识点来说,重温四⼤组件最好的⽅式就是跟着源码再⾛⼀遍,说起看源码,我们可能会⽐较头疼,这是因为⼀旦扎进去,就会陷在代码的海洋⾥,不知所措,其实分析源码,最忌讳的是⼀上来就深挖。这样很难出来,不仅费时间,⽽且也提取不到有⽤的信息,最好的⽅式就是先按照主线流程⾛⼀遍,先把主线打通,有时间的话,再对⽀线进⾏旁敲侧击。
好,现在按照我们刚刚讲的⽅式来分析,今天我们主要分析service的启动流程,⾸先我们知道启动service有两种⽅式:startService和bindService,也就是service的启动和绑定,接下来我们先分析service的启动。
startService
⾸先我们从context.startService()这个⽅法为起点进⾏分析,我们看下他的源码:
@Override
public ComponentName startService(Intent service){
return mBase.startService(service);
}
startService()是⼀个抽象⽅法,具体实现在ContextImpl.java⾥,进⼊ContextImpl.java看下:
@Override
public ComponentName startService(Intent service){
warnIfCallingFromSystemProcess();
return startServiceCommon(service,false, mUser);
}
⼜会直接⾛到startServiceCommon这个⽅法⾥,
private ComponentName startServiceCommon(Intent service,boolean requireForeground, UserHandle user){
try{
validateServiceIntent(service);
service.prepareToLeaveProcess(this);
ComponentName cn = Service().startService(
getOpPackageName(),getAttributionTag(), Identifier());
if(cn != null){
PackageName().equals("!")){
throw new SecurityException(
"Not allowed to start service "+ service
+" without permission "+ cn.getClassName());
}else PackageName().equals("!!")){
throw new SecurityException(
"Unable to start service "+ service
+": "+ cn.getClassName());
}else PackageName().equals("?")){
throw new IllegalStateException(
"Not allowed to start service "+ service +": "+ cn.getClassName());
}
}
return cn;
}catch(RemoteException e){
hrowFromSystemServer();
}
}
从startServiceCommon这个⽅法中,很容易定位到重点代码:
ComponentName cn = Service().startService(
getOpPackageName(),getAttributionTag(), Identifier());
通过Service()就会⾛到AMS中,在AMS⾥来启动service。
接下来进⼊AMS,⼀探究竟:
@Override
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType,boolean requireForeground, String callingPackage,
String callingFeatureId,int userId)
throws TransactionTooLargeException {
...
try{
res = mServices.startServiceLocked(caller, service,
resolvedType, callingPid, callingUid,
requireForeground, callingPackage, callingFeatureId, userId);
}finally{
}
return res;
}
}
在这个⽅法⾥,会通过ActiveServices调⽤startServiceLocked,再看startServiceLocked:
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,int callingPid,int callingUid,boolean fgRequired, String callingPackage,
@Nullable String callingFeatureId,final int userId,
boolean allowBackgroundActivityStarts)throws TransactionTooLargeException {
if(DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE,"startService: "+ service
+" type="+ resolvedType +" args="+ Extras());
final boolean callerFg;
if(caller != null){
// 这⾥记录app的进程信息
final ProcessRecord callerApp = RecordForAppLocked(caller);
...
ComponentName cmp =startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
...
return cmp;
}
最终调⽤startServiceInnerLocked,继续看这个⽅法:
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,boolean callerFg,boolean addToStarting)throws Transacti onTooLargeException {
...
String error =bringUpServiceLocked(r, Flags(), callerFg,false,false);
if(error != null){
return new ComponentName("!!", error);
}
...
return r.name;
}
继续调⽤了bringUpServiceLocked,
private String bringUpServiceLocked(ServiceRecord r,int intentFlags,boolean execInFg,boolean whileRestarting,boolean permissionsReviewRequired) throws TransactionTooLargeException {
...
// Service is now being launched, its package can't be stopped.
try{
r.packageName,false, r.userId);
}catch(RemoteException e){
}catch(IllegalArgumentException e){
制作android软件流程Slog.w(TAG,"Failed trying to unstop package "
+ r.packageName +": "+ e);
}
final boolean isolated =(r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS)!=0;
final String procName = r.processName;
HostingRecord hostingRecord =new HostingRecord("service", r.instanceName);
ProcessRecord app;
if(!isolated){
app = ProcessRecordLocked(procName, r.appInfo.uid,false);
if(DEBUG_MU) Slog.v(TAG_MU,"bringUpServiceLocked: appInfo.uid="+ r.appInfo.uid +" app="+ app);
//如果service进程存在
if(app != null && app.thread != null){
try{
app.addPackage(r.appInfo.packageName, r.appInfo.longVersionCode, mAm.mProcessStats);
//启动service
realStartServiceLocked(r, app, execInFg);
return null;
}catch(TransactionTooLargeException e){
throw e;
}catch(RemoteException e){
Slog.w(TAG,"Exception when starting service "+ r.shortInstanceName, e);
}
}
}else{
app = r.isolatedProc;
if(WebViewZygote.isMultiprocessEnabled()
&& r.serviceInfo.packageName.PackageName())){
hostingRecord = HostingRecord.byWebviewZygote(r.instanceName);
}
if((r.serviceInfo.flags & ServiceInfo.FLAG_USE_APP_ZYGOTE)!=0){
hostingRecord = HostingRecord.byAppZygote(r.instanceName, r.definingPackageName,
r.definingUid);
}
}
// 如果不存在此进程
if(app == null &&!permissionsReviewRequired){
// 启动运⾏的线程
if((app=mAm.startProcessLocked(procName, r.appInfo,true, intentFlags,
hostingRecord, ZYGOTE_POLICY_FLAG_EMPTY,false, isolated,false))== null){
String msg ="Unable to launch app "
+ r.appInfo.packageName +"/"
+ r.appInfo.uid +" for service "
+ Intent()+": process is bad";
Slog.w(TAG, msg);
bringDownServiceLocked(r);
return msg;
}
if(isolated){
r.isolatedProc = app;
}
}
...
return null;
}
这个⽅法做了两件事:
1.如果Service进程已经存在,则直接调⽤realStartServiceLocked。
2.如果Service进程不存在,则执⾏startProcessLocked⽅法创建进程,经过层层调⽤,最终也会⾛到
realStartServiceLocked中。
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app,boolean execInFg)throws RemoteException {
...
try{
...
app.thread.scheduleCreateService(r, r.serviceInfo,
mAmpatibilityInfoForPackage(r.serviceInfo.applicationInfo),
r.postNotification();
created =true;
}
}
这个⽅法内部调⽤了app.thread.scheduleCreateService,⽽app.thread是⼀个IApplicationThread类型的,他的实现是ActivityThread的⼀个内部类ApplicationThread,⽽这个类正好实现了IApplicationThread.Stub,在ApplicationThread类中,到对应的调⽤⽅法:
public final void scheduleCreateService(IBinder token,
ServiceInfo info, CompatibilityInfo compatInfo,int processState){
updateProcessState(processState,false);
CreateServiceData s =new CreateServiceData();
s.info = info;
spatInfo = compatInfo;
sendMessage(H.CREATE_SERVICE, s);
}
可以看出,是发送⼀个消息给Handler,这个Handler是ActivityThread的内部类H
public void handleMessage(Message msg){
switch(msg.what){
...
case CREATE_SERVICE:
if(Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)){
("serviceCreate: "+ String.valueOf(msg.obj)));
}
handleCreateService((CreateServiceData)msg.obj);
break;
...
}
}
最终调⽤了handleCreateService⽅法:
private void handleCreateService(CreateServiceData data){
LoadedApk packageInfo =getPackageInfoNoCheck(
data.info.applicationInfo, datapatInfo);
Service service = null;
try{
//创建service的context
ContextImpl context = ateAppContext(this, packageInfo);
//创建Application
Application app = packageInfo.makeApplication(false, mInstrumentation);
//获取类加载器
java.lang.ClassLoader cl = ClassLoader();
//加载service实例
service = AppFactory()
.instantiateService(cl, data.info.name, data.intent);
// Service resources must be initialized with the same loaders as the application // context.
context.setOuterContext(service);
//初始化service
service.attach(context,this, data.info.name, ken, app,
//调⽤service的onCreate⽅法
mServices.ken, service);
try{
//通过serviceDoneExecuting告知AMS,service已经启动完成
}catch(RemoteException e){
hrowFromSystemServer();
}
}catch(Exception e){
if(!Exception(service, e)){
throw new RuntimeException(
"Unable to create service "+ data.info.name
+": "+ e.toString(), e);
}
}
}
来看下这个⽅法做了哪些事情:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论