startService启动流程---Service在App进程但未启动

2023-10-11 21:48

本文主要是介绍startService启动流程---Service在App进程但未启动,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在Service启动流程(startService)的最后,分析了在调用startService时可能存在的三种情况,本文分析第二种情况—Service与App在同一个进程,但未启动。

Service启动流程(startService)最后已经说明,在这种情况下,系统会执行realStartServiceLocked函数。

private final void realStartServiceLocked(ServiceRecord r,ProcessRecord app) throws RemoteException {......r.app = app;r.restartTime = r.lastActivity = SystemClock.uptimeMillis();app.services.add(r);bumpServiceExecutingLocked(r, "create");updateLruProcessLocked(app, true, true);boolean created = false;try {......//跨进程去执行Service实例的创建app.thread.scheduleCreateService(r, r.serviceInfo,compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));r.postNotification();created = true;} finally {if (!created) {app.services.remove(r);scheduleServiceRestartLocked(r, false);}}......//Service创建完成后,执行onStartCommand函数sendServiceArgsLocked(r, true);
}  

函数的逻辑还是比较清晰的,完成的工作主要有两个:

  • 创建Service实例
  • 执行onStartCommand方法

接下来就来看下这两个任务时如何完成的。

创建Service实例是一个Binder跨进程调用,Binder细节就不分析,直接进入ActivityThread查看scheduleCreateService的实现

public final void scheduleCreateService(IBinder token,ServiceInfo info, CompatibilityInfo compatInfo) {CreateServiceData s = new CreateServiceData();s.token = token;s.info = info;s.compatInfo = compatInfo;queueOrSendMessage(H.CREATE_SERVICE, s);}  

好吧,queueOrSendMessage这个函数我们在ActivityThread中已经看到过很多次调用很多次了,我们直接进入到真正执行创建Service实例的函数queueOrSendMessage

private void handleCreateService(CreateServiceData data) {// If we are getting ready to gc after going to the background, well// we are back active so skip it.......LoadedApk packageInfo = getPackageInfoNoCheck(data.info.applicationInfo, data.compatInfo);Service service = null;try {//反射创建Service实例java.lang.ClassLoader cl = packageInfo.getClassLoader();service = (Service) cl.loadClass(data.info.name).newInstance();} catch (Exception e) {if (!mInstrumentation.onException(service, e)) {throw new RuntimeException("Unable to instantiate service " + data.info.name+ ": " + e.toString(), e);}}try {......ContextImpl context = new ContextImpl();context.init(packageInfo, null, this);Application app = packageInfo.makeApplication(false, mInstrumentation);context.setOuterContext(service);service.attach(context, this, data.info.name, data.token, app,ActivityManagerNative.getDefault());//执行Service onCreate方法service.onCreate();mServices.put(data.token, service);try {//通知ActivityManagerService实例创建完成ActivityManagerNative.getDefault().serviceDoneExecuting(data.token, 0, 0, 0);} catch (RemoteException e) {// nothing to do.}} catch (Exception e) {if (!mInstrumentation.onException(service, e)) {throw new RuntimeException("Unable to create service " + data.info.name+ ": " + e.toString(), e);}}
}

函数的代码不短也不长,还是比较好理解的。首先获取Service的信息,然后调用反射创建Service实例(想想Activity实例的创建,是不是也是反射?),创建完实例后就会去执行attach方法,执行完attach方法后就会去执行onCreate方法(想想Activity,是不是也是先执行attach在执行onCreate?),执行完onCreate方法后,通知ActivityManagerService。

执行完Service实例的创建,接下来执行onStartCommand的流程就是 startService启动流程—Service已经启动中描述的流程,我就不再分析了。

这篇关于startService启动流程---Service在App进程但未启动的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/191038

相关文章

SpringBoot启动报错的11个高频问题排查与解决终极指南

《SpringBoot启动报错的11个高频问题排查与解决终极指南》这篇文章主要为大家详细介绍了SpringBoot启动报错的11个高频问题的排查与解决,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一... 目录1. 依赖冲突:NoSuchMethodError 的终极解法2. Bean注入失败:No qu

一文带你了解SpringBoot中启动参数的各种用法

《一文带你了解SpringBoot中启动参数的各种用法》在使用SpringBoot开发应用时,我们通常需要根据不同的环境或特定需求调整启动参数,那么,SpringBoot提供了哪些方式来配置这些启动参... 目录一、启动参数的常见传递方式二、通过命令行参数传递启动参数三、使用 application.pro

SpringBoot项目启动报错"找不到或无法加载主类"的解决方法

《SpringBoot项目启动报错找不到或无法加载主类的解决方法》在使用IntelliJIDEA开发基于SpringBoot框架的Java程序时,可能会出现找不到或无法加载主类com.example.... 目录一、问题描述二、排查过程三、解决方案一、问题描述在使用 IntelliJ IDEA 开发基于

Linux中的进程间通信之匿名管道解读

《Linux中的进程间通信之匿名管道解读》:本文主要介绍Linux中的进程间通信之匿名管道解读,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、基本概念二、管道1、温故知新2、实现方式3、匿名管道(一)管道中的四种情况(二)管道的特性总结一、基本概念我们知道多

Android App安装列表获取方法(实践方案)

《AndroidApp安装列表获取方法(实践方案)》文章介绍了Android11及以上版本获取应用列表的方案调整,包括权限配置、白名单配置和action配置三种方式,并提供了相应的Java和Kotl... 目录前言实现方案         方案概述一、 androidManifest 三种配置方式

Linux进程终止的N种方式详解

《Linux进程终止的N种方式详解》进程终止是操作系统中,进程的一个重要阶段,他标志着进程生命周期的结束,下面小编为大家整理了一些常见的Linux进程终止方式,大家可以根据需求选择... 目录前言一、进程终止的概念二、进程终止的场景三、进程终止的实现3.1 程序退出码3.2 运行完毕结果正常3.3 运行完毕

Spring AI ectorStore的使用流程

《SpringAIectorStore的使用流程》SpringAI中的VectorStore是一种用于存储和检索高维向量数据的数据库或存储解决方案,它在AI应用中发挥着至关重要的作用,本文给大家介... 目录一、VectorStore的基本概念二、VectorStore的核心接口三、VectorStore的

python之流程控制语句match-case详解

《python之流程控制语句match-case详解》:本文主要介绍python之流程控制语句match-case使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录match-case 语法详解与实战一、基础值匹配(类似 switch-case)二、数据结构解构匹

MyBatis-Plus中Service接口的lambdaUpdate用法及实例分析

《MyBatis-Plus中Service接口的lambdaUpdate用法及实例分析》本文将详细讲解MyBatis-Plus中的lambdaUpdate用法,并提供丰富的案例来帮助读者更好地理解和应... 目录深入探索MyBATis-Plus中Service接口的lambdaUpdate用法及示例案例背景

Windows命令之tasklist命令用法详解(Windows查看进程)

《Windows命令之tasklist命令用法详解(Windows查看进程)》tasklist命令显示本地计算机或远程计算机上当前正在运行的进程列表,命令结合筛选器一起使用,可以按照我们的需求进行过滤... 目录命令帮助1、基本使用2、执行原理2.1、tasklist命令无法使用3、筛选器3.1、根据PID