Service组件StartService()方式启动流程分析

1.前言

    AMS(ActivityManagerService)是Android四大组件工作的核心服务类,Activity和Service的启动过程均由其完成。本次基于Android SDK28梳理一下Service的启动流程,加深对Service组件的理解,也有利于更好的定位开发中的问题。
注:由于本次关注的重点是启动流程,因此多余的无关代码没粘贴出来。

2. startService()方式启动Service流程

一般我们调用Context.startService(),最后的实现都是在ContextImpl中的。

2.1 ContextImpl->startService():
@Override
public ComponentName startService(Intent service) {
    warnIfCallingFromSystemProcess();
    return startServiceCommon(service, false, mUser); 
}
2.2 startServiceCommon()方法的实现如下:
private ComponentName startServiceCommon(Intent service, boolean requireForeground,
            UserHandle user) {
    validateServiceIntent(service);
    service.prepareToLeaveProcess(this);
    //转调到AMS#startService(),而AMS是运行在system_server进程的,这里是跨进程调用,从应用进程转调到系统进程。
    ComponentName cn = ActivityManager.getService().startService(
                mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
                            getContentResolver()), requireForeground, getOpPackageName(), 
                            user.getIdentifier());
}
2.3 系统进程: AMS->startService():
    @Override
    public ComponentName startService(IApplicationThread caller, Intent service,
            String resolvedType, boolean requireForeground, String callingPackage, int userId)
            throws TransactionTooLargeException {
        enforceNotIsolatedCaller("startService");
        synchronized(this) {
          final int callingPid = Binder.getCallingPid();
          final int callingUid = Binder.getCallingUid();
          final long origId = Binder.clearCallingIdentity();
          //mServices是ActiveServices类型的实例,在AMS的构造函数中直接new出来的
          //转调到:ActivityServices->startServiceLocked()
          ComponentName res = mServices.startServiceLocked(caller, service,
                        resolvedType, callingPid, callingUid,
                        requireForeground, callingPackage, userId);
          return res;
        }
    }
2.4 ActivityServices->startServiceLocked():
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
            int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId)
            throws TransactionTooLargeException {
       ...
	   ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
	   ...
}
2.5 ActivityServices->startServiceInnerLocked():
    ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
            boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
            ...
            String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
            ...
}
2.6 ActivityServices->bringUpServiceLocked():
    private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
            boolean whileRestarting, boolean permissionsReviewRequired)
            throws TransactionTooLargeException {
		app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
        if (app != null && app.thread != null) {
           ...
           app.addPackage(r.appInfo.packageName, r.appInfo.longVersionCode, mAm.mProcessStats);
           //转调到realStartServiceLocked继续下一步流程
           realStartServiceLocked(r, app, execInFg);
           return null;
           ...
        }            
}
2.7 ActivityServices->realStartServiceLocked():
private final void realStartServiceLocked(ServiceRecord r,
            ProcessRecord app, boolean execInFg) throws RemoteException {
		app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
		//ipc调用:ApplicationThread->scheduleCreateService
        app.thread.scheduleCreateService(r, r.serviceInfo, mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
        app.repProcState);            
}
2.8 应用进程:ActivityThread.ApplicationThread->scheduleCreateService():
public final void scheduleCreateService(IBinder token, ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
       updateProcessState(processState, false);
       CreateServiceData s = new CreateServiceData();
       s.token = token;
       s.info = info;
       s.compatInfo = compatInfo;
       //此方法是间接调用了ActivityThread中的handler将消息发送到主线程,交给handleMessage处理
       sendMessage(H.CREATE_SERVICE, s);
}

    这里要清楚的一个点是,AMS是运行在系统进程的,Service是运行在应用进程的,那就需要一个中介,去完成从AMS在system_server中完成Service的配置项、注册之后,再转回到应用进程,这个就是定义在android.app.ActivityThread.java文件中的ApplicationThread,本质是一个binder接口,他完成了从系统进程转到应用进程的逻辑。

2.9 处理message: ActivityThread.H->handleMessage():

  case CREATE_SERVICE:
       handleCreateService((CreateServiceData)msg.obj);
       break;
2.10 handleCreateService():检查应用进程是否启动,通过反射创建Service实例,调用onCreate()方法
private void handleCreateService(CreateServiceData data) {
        LoadedApk packageInfo = getPackageInfoNoCheck(data.info.applicationInfo, data.compatInfo);
        Service service = null;
        java.lang.ClassLoader cl = packageInfo.getClassLoader();
        //通过Service的className,反射创建Service对象
        service = packageInfo.getAppFactory().instantiateService(cl, data.info.name, data.intent);
        ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
        context.setOuterContext(service);
		//makeApplication():如果Application还未初始化就会反射创建application对象返回
        Application app = packageInfo.makeApplication(false, mInstrumentation);
        service.attach(context, this, data.info.name, data.token, app, ActivityManager.getService());
        //回调onCreate()
        service.onCreate();	
         //将上面创建的Service实例缓存下来,在进行绑定,解绑,或者回调stop时会直接从缓存中获取
        mServices.put(data.token, service);
    }
    
	//CreateServiceData数据结构
 	static final class CreateServiceData {
    	IBinder token;
   	 	ServiceInfo info;
    	CompatibilityInfo compatInfo;
   		Intent intent;
   		...
	}
2.11 Service->onCreate():到这一步Service的创建和启动过程完毕,本质上是先反射创建一个Service实例,然后回调onCreate()。但是组件启动都会先检查Application实例是否存在,不存在都会先makeApplication()创建Application实例。
//Service已经完成创建,回调Service的onCreate方法
public void onCreate() {
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TechMix

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值