美文网首页
Android Service启动流程

Android Service启动流程

作者: feifei_fly | 来源:发表于2020-12-12 14:41 被阅读0次

一、Service生命周期

首先我们先回忆一下Service的声明周期

image
  • 第一次调用startServie(): Service.onCreate()->Service.onStartCommand()
  • 第二次调用startService(): Service.onStartCommand()

本周主要分析上面两步操作,Service的启动行为。

二、Service启动分析

image

阶段一:app进程startService(),向SystemServer进程发送启动Service的请求

首先明确一点,启动Service、启动Activity、发送广播,这些都是Context上下文的本职工作。
在Applciation、Activity或者Service中都可以调用startService(),最终会调用到ContextImpl.startService()

  • ContextImpl.StartService
  • ContextImpl.startServiceCommon
  • ActivityManager.getService().startService()

阶段二:SystemService进程 处理启动Service请求

在ActivityManagerService中,启动service的操作 是委托给ActiveServices执行的。

  • ActivityManagerService.startService()
  • ActiveServices.startServiceLocked()

startServiceLocked方法中会解析要启动的Service,创建对应的ServiceRecord实例,最终调用自身bringUpServiceLocked方法。

## ActiveServices.java
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId)
throws TransactionTooLargeException {

    //(1)解析、创建响应的ServiceRecord
  ServiceLookupResult res =retrieveServiceLocked(service, resolvedType, callingPackage,
                    callingPid, callingUid, userId, true, callerFg, false, false);

 ServiceRecord r = res.record;  

 //(2)调用内部方法
  ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);       

}
  • ActiveServices.startServiceInnerLocked()
  • ActiveServices.bringUpServiceLocked()

bringUpServiceLocked是处理Service启动逻辑的核心方法。

 private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
            boolean whileRestarting, boolean permissionsReviewRequired)
            throws TransactionTooLargeException {


//注释一:如果Service已经创建,则直接调用sendServiceArgsLocked(),最终会触发Service.onStartCommand()方法调用
 if (r.app != null && r.app.thread != null) {
            sendServiceArgsLocked(r, execInFg, false);
            return null;
        }
        
 final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;

  if (!isolated) {  
     
     //注释二:非独立进程,则直接启动Service:onCreate(),onStartCommad()方法
      realStartServiceLocked(r, app, execInFg);

  }else {
        //注释三: 如果Service要运行独立进程,且进程不存在,则创建新进程.      
        if (app == null && !permissionsReviewRequired) {
                if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
                        hostingType, r.name, false, isolated, false)) == null) {
                    String msg = "Unable to launch app "
                            + r.appInfo.packageName + "/"
                            + r.appInfo.uid + " for service "
                            + r.intent.getIntent() + ": process is bad";
                    Slog.w(TAG, msg);
                    bringDownServiceLocked(r);
                    return msg;
                }
                if (isolated) {
                    r.isolatedProc = app;
                }
        }
           
  }
}
  • 注释一:如果Service已经创建,则直接调用sendServiceArgsLocked(),最终调用Service.onStartCommand()方法。对应第二次调用StartService方法的场景,此场景Service仅会回调onStartCommand()回调
  • 注释二:如果Service不要求运行在新的进程,则调用realStartServiceLocked()方法,该方法 会触发Service.onCreate()和onStartCommand()方法
  • 注释三: 如果Service要运行独立进程,且进程不存在,则创建新进程.

阶段三:ActivityMangaerService 与 ActivityThread IPC互动过程。

下面我们一起来看一下ActiveServices是 如何创建,并启动Service的。

核心方法在realStartServiceLocked()

private final void realStartServiceLocked(ServiceRecord r,
    ProcessRecord app, boolean execInFg) throws RemoteException {

    //(1)向ApplicationThread发送消息,创建Service
   app.thread.scheduleCreateService(r, r.serviceInfo,
                mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
                app.repProcState);

    //(2)向Service发送参数
    sendServiceArgsLocked(r, execInFg, true);
}

1、scheduleCreateService

利用ApplicationThread 向app进程发送IPC消息

  • ApplicationThread.scheduleCreateService()
  • ApplicationThread发送H.CREATE_SERVICE消息
  • ActivityThread.handleCreateService()
private void handleCreateService(CreateServiceData data) {

    //(1)创建Service
   service = packageInfo.getAppFactory()
            .instantiateService(cl, data.info.name, data.intent);
    //(2)创建ContextImpl
   ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
            context.setOuterContext(service);
   //(3)调用Service.attah()
  service.attach(context, this, data.info.name, data.token, app,
        ActivityManager.getService());
   //(4)调用Service.onCreate()
   service.onCreate();
 }

handleCreateService()中完成了以下操作:

  • 利用LoaedApk创建了Service实例,
  • 创建ContextImpl()实例
  • 调用Service.attach()完成ContextImpl的绑定
  • 调用Service.onCreate()方法

2、 sendServiceArgsLocked 启动Service的参数处理

ActiveServices.sendServiceArgsLocked 主要做的操作就是,通过ApplicationThread发送scheduleServiceArgs的IPC消息

private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,boolean oomAdjusted) throws TransactionTooLargeException {
      r.app.thread.scheduleServiceArgs(r, slice);
}
  • ApplicationThread.scheduleServiceArgs()
 public final void scheduleServiceArgs(IBinder token, ParceledListSlice args) {
            List<ServiceStartArgs> list = args.getList();

            for (int i = 0; i < list.size(); i++) {
                ServiceStartArgs ssa = list.get(i);
                ServiceArgsData s = new ServiceArgsData();
                s.token = token;
                s.taskRemoved = ssa.taskRemoved;
                s.startId = ssa.startId;
                s.flags = ssa.flags;
                s.args = ssa.args;

                sendMessage(H.SERVICE_ARGS, s);
            }
        }

  • 发送H.SERVICE_ARGS 消息
  • ActivityThread.handleServiceArgs(),调用Service.onStartCommand()

  private void handleServiceArgs(ServiceArgsData data) {
     Service s = mServices.get(data.token);
      if (!data.taskRemoved) {
            res = s.onStartCommand(data.args, data.flags, data.startId);
        } else {
            s.onTaskRemoved(data.args);
            res = Service.START_TASK_REMOVED_COMPLETE;
        }
  }  

三、参考文章

https://www.jianshu.com/p/cc25fbb5c0b3
https://www.jianshu.com/p/e65cfcbdd11e

相关文章

网友评论

      本文标题:Android Service启动流程

      本文链接:https://www.haomeiwen.com/subject/cznegktx.html