Android Service启动流程

2020-12-12  本文已影响0人  feifei_fly

一、Service生命周期

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

image

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

二、Service启动分析

image

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

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

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

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

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);       

}

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;
                }
        }
           
  }
}

阶段三: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消息

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()中完成了以下操作:

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);
}
 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);
            }
        }


  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

上一篇 下一篇

猜你喜欢

热点阅读