Android中Service在新进程中的启动流程

       

目录

1、Service与AMS交互框架介绍

1.1、认识AMS代表IActivityManager

1.2、认识客户端代表IApplicationThread

2、Service启动流程概览


        我们知道Android有四大组件,Activity、Service、ContentProvider、Broadcast,每个组件在系统运行中或者我们编写应用程序的过程中都起到举足轻重的作用,其中的Service主要用于做一些后台计算的问题,该篇文章介绍Service的启动流程概览,让你更加对Service有深入的理解,分析源码基于Android2.3.7。

1、Service与AMS交互框架介绍

        App中的Service与AMS的交互框架如下:

        这里涉及到两个进程,三个主体:

  • 首先是我们的App进程,假定MyService服务运行于服务进程(还没有启动,我们暂称为Service进程吧,从APP进程中调用startService启动)中 ,我们调用startService启动服务后,AMS会通过binder驱动回调到我们的Service进程,调用Service里面的生命周期函数。
  • 其次是AMS服务,该服务运行于system_server进程,用于接收并处理APP进程发送过来的请求,比如我们这里的startService,处理完成后回调到相应的客户端进程,如MyService进程。

        MyService服务由客户端进程实现,我们假设它在一个新进程中启动,它在与AMS通信时是通过远程接口IActivityManager与AMS通信的,这里的IActivityManager接口之所以说是远程接口是因为它的实现在AMS服务这一侧,而该服务运行于系统进程system_server中,而MyService则是运行于MyService进程,它们并不是在同一个进程。

        MyService进程通过代理ActivityManagerProxy与AMS交互,而它们之间通信的基础则是binder驱动。

ActivityManagerProxy实现了IActivityManager接口,客户端实际上是用ActivityManagerProxy与AMS通信。

1.1、认识AMS代表IActivityManager

        下面我们来认识下IActivityManager,看看它有哪些与服务相关的接口,源码如下:

/**
 * System private API for talking with the activity manager service.  This
 * provides calls from the application back to the activity manager.
 *
 * {@hide}
 */
public interface IActivityManager extends IInterface {
    //...
    public ComponentName startService(IApplicationThread caller, Intent service,
            String resolvedType) throws RemoteException;
    public int stopService(IApplicationThread caller, Intent service,
            String resolvedType) throws RemoteException;
    public boolean stopServiceToken(ComponentName className, IBinder token,
            int startId) throws RemoteException;
    public void setServiceForeground(ComponentName className, IBinder token,
            int id, Notification notification, boolean keepNotification) throws RemoteException;
    public int bindService(IApplicationThread caller, IBinder token,
            Intent service, String resolvedType,
            IServiceConnection connection, int flags) throws RemoteException;
    public boolean unbindService(IServiceConnection connection) throws RemoteException;
    public void publishService(IBinder token,
            Intent intent, IBinder service) throws RemoteException;
    public void unbindFinished(IBinder token, Intent service,
            boolean doRebind) throws RemoteException;
    /* oneway */
    public void serviceDoneExecuting(IBinder token, int type, int startId,
            int res) throws RemoteException;
    public IBinder peekService(Intent service, String resolvedType) throws RemoteException;

    //....

}

        该文件接口比较多,这里只摘取了与Service相关的一些接口:

  • startService:启动服务(该接口的实现位于AMS侧)
  • stopService:停止服务(该接口的实现位于AMS侧)
  • bindService:绑定服务(该接口的实现位于AMS侧)
  • unbindService:解绑服务(该接口的实现位于AMS侧)

        以上接口由AMS实现;AMS处理完客户端的请求后,需要告诉MyService进程,并让MyService进程执行生命周期,此时AMS则通过IApplicationThread与MyService进程通信,IApplicationThread其实就是MyService进程的代表。

1.2、认识客户端代表IApplicationThread

        下面我们认识下IApplicationThread,部分源码如下:

/**
 * System private API for communicating with the application.  This is given to
 * the activity manager by an application  when it starts up, for the activity
 * manager to tell the application about things it needs to do.
 *
 * {@hide}
 */
public interface IApplicationThread extends IInterface {
    //...
    void schedulePauseActivity(IBinder token, boolean finished, boolean userLeaving,
            int configChanges) throws RemoteException;
    void scheduleStopActivity(IBinder token, boolean showWindow,
            int configChanges) throws RemoteException;
    void scheduleWindowVisibility(IBinder token, boolean showWindow) throws RemoteException;
    void scheduleResumeActivity(IBinder token, boolean isForward) throws RemoteException;
    void scheduleSendResult(IBinder token, List<ResultInfo> results) throws RemoteException;
    void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
            ActivityInfo info, Bundle state, List<ResultInfo> pendingResults,
    		List<Intent> pendingNewIntents, boolean notResumed, boolean isForward)
    		throws RemoteException;
    void scheduleRelaunchActivity(IBinder token, List<ResultInfo> pendingResults,
            List<Intent> pendingNewIntents, int configChanges,
            boolean notResumed, Configuration config) throws RemoteException;
    void scheduleNewIntent(List<Intent> intent, IBinder token) throws RemoteException;
    void scheduleDestroyActivity(IBinder token, boolean finished,
            int configChanges) throws RemoteException;
    void scheduleReceiver(Intent intent, ActivityInfo info, int resultCode,
            String data, Bundle extras, boolean sync) throws RemoteException;
    static final int BACKUP_MODE_INCREMENTAL = 0;
    static final int BACKUP_MODE_FULL = 1;
    static final int BACKUP_MODE_RESTORE = 2;
    void scheduleCreateBackupAgent(ApplicationInfo app, int backupMode) throws RemoteException;
    void scheduleDestroyBackupAgent(ApplicationInfo app) throws RemoteException;
    void scheduleCreateService(IBinder token, ServiceInfo info) throws RemoteException;
    void scheduleBindService(IBinder token,
            Intent intent, boolean rebind) throws RemoteException;
    void scheduleUnbindService(IBinder token,
            Intent intent) throws RemoteException;
    void scheduleServiceArgs(IBinder token, int startId, int flags, Intent args)
            throws RemoteException;
    void scheduleStopService(IBinder token) throws RemoteException;
    static final int DEBUG_OFF = 0;
    static final int DEBUG_ON = 1;
    static final int DEBUG_WAIT = 2;
    void bindApplication(String packageName, ApplicationInfo info, List<ProviderInfo> providers,
            ComponentName testName, String profileName, Bundle testArguments, 
            IInstrumentationWatcher testWatcher, int debugMode, boolean restrictedBackupMode,
            Configuration config, Map<String, IBinder> services) throws RemoteException;
    void scheduleExit() throws RemoteException;
    void scheduleSuicide() throws RemoteException;
    void requestThumbnail(IBinder token) throws RemoteException;
    void scheduleConfigurationChanged(Configuration config) throws RemoteException;
    void updateTimeZone() throws RemoteException;
    void processInBackground() throws RemoteException;
    void dumpService(FileDescriptor fd, IBinder servicetoken, String[] args)
            throws RemoteException;
    void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
            int resultCode, String data, Bundle extras, boolean ordered, boolean sticky)
            throws RemoteException;
    void scheduleLowMemory() throws RemoteException;
    void scheduleActivityConfigurationChanged(IBinder token) throws RemoteException;
    void profilerControl(boolean start, String path, ParcelFileDescriptor fd)
            throws RemoteException;
    void setSchedulingGroup(int group) throws RemoteException;
    void getMemoryInfo(Debug.MemoryInfo outInfo) throws RemoteException;
    static final int PACKAGE_REMOVED = 0;
    static final int EXTERNAL_STORAGE_UNAVAILABLE = 1;
    void dispatchPackageBroadcast(int cmd, String[] packages) throws RemoteException;
    void scheduleCrash(String msg) throws RemoteException;
    
    String descriptor = "android.app.IApplicationThread";
    //...
}

        与Service相关的接口如下:

  • scheduleCreateService:创建服务,会调用服务的onCreate生命周期函数。
  • scheduleBindService:绑定服务,会调用服务的onBind函数。
  • scheduleUnbindService:解绑服务,会调用服务的unBind函数。
  • scheduleServiceArgs:调用服务的onStart函数。
  • scheduleStopService:停止服务,调用服务的onStop函数。

        以上的函数运行于MyService进程,由客户端实现。

2、Service启动流程概览

        如下图所示为Service启动的总体流程:

        如上面的流程图,Service启动总共分为以上8个步骤,接下来我们就按照这个8个步骤分析下Service是如何通过调用startService一步步启动的,在执行每一步的过程中希望读者清楚当前每一步是在哪个进程执行,这样才能真正理解为何启动Service时与AMS的具体交互是怎样的,同时有助于理解启动服务过程中为何会产生ANR。

        好了,启动流程概览基本说完了;下一篇我们在具体解析startService的启动流程。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/958715.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

华为EC6110T-海思Hi3798MV310_安卓9.0_通刷-强刷固件包

华为EC6110T-海思Hi3798MV310_安卓9.0_通刷-强刷固件包 刷机教程说明&#xff1a; 适用机型&#xff1a;华为EC6110-T、华为EC6110-U、华为EC6110-M 破解总分为两个部分&#xff1a;拆机短接破解&#xff08;保留IPTV&#xff09;和OTT卡刷&#xff08;不保留IPTV&#xff09…

2025.1.20——二、buuctf BUU UPLOAD COURSE 1 1 文件上传

题目来源&#xff1a;buuctf BUU UPLOAD COURSE 1 1 目录 一、打开靶机&#xff0c;查看信息 二、解题思路 step 1&#xff1a;上传一句话木马.php文件康康回显 step 2&#xff1a;蚁剑连接 三、小结 一、打开靶机&#xff0c;查看信息 这里提示到了文件会被上传到./uplo…

移动端VR处理器和传统显卡的不同

骁龙 XR 系列芯片 更多地依赖 AI 技术 来优化渲染过程&#xff0c;而传统的 GPU 渲染 则倾向于在低画质下运行以减少负载。这种设计是为了在有限的硬件资源下&#xff08;如移动端 XR 设备&#xff09;实现高性能和低功耗的平衡。以下是具体的分析&#xff1a; 1. AI 驱动的渲染…

[java] java基础-字符串篇

目录 API String 创建字符串对象的两种方式&#xff1a; Java的内存模型 字符串常量池&#xff08;串池&#xff09;存放地址 两种构造方法的内存分析 String的常用方法 号比较的是什么 字符串比较&#xff08;比较字符串的数据值&#xff09; 遍历字符串 StringBui…

C# 多线程同步(Mutex | Semaphore)

Mutex: 用于保护临界区&#xff0c;确保同一时间只有一个线程能够访问共享资源&#xff1b; Semaphore: 允许同时有多个线程访问共享资源&#xff0c;但会限制并发访问的数量。 Mutex运行输出 Semaphore运行输出 namespace SyncThreadDemo {internal class Program{static stri…

易语言模拟真人鼠标轨迹算法 - 防止游戏检测

一.简介 鼠标轨迹算法是一种模拟人类鼠标操作的程序&#xff0c;它能够模拟出自然而真实的鼠标移动路径。 鼠标轨迹算法的底层实现采用C/C语言&#xff0c;原因在于C/C提供了高性能的执行能力和直接访问操作系统底层资源的能力。 鼠标轨迹算法具有以下优势&#xff1a; 模拟…

ThinkPhp伪静态设置后,访问静态资源也提示找不到Controller

ThinkPhp没有配置伪静态时&#xff0c;除了默认的IndexController能访问&#xff0c;其他路由Controller都访问不到&#xff0c;提示404错误。配置了伪静态后就解决了这个问题。 但是当我的ThinkPhp后台项目中有静态资源放在public目录&#xff08;或子目录&#xff09;中需要…

C#编译报错: error CS1069: 未能在命名空间“System.Windows.Markup”中找到类型名“IComponentConnector”

文章目录 问题现象解决方案 问题现象 一个以前使用.NET Framwork 3.0框架开发的项目&#xff0c;在框架升级到.NET Framwork 4.7.2后&#xff0c; 如下代码&#xff1a; #pragma checksum "..\..\XpsViewer.xaml" "{8829d00f-11b8-4213-878b-770e8597ac16}&qu…

在宝塔安装部署mindoc

MinDoc简介 MinDoc 是一款针对IT团队开发的简单好用的文档管理系统。 MinDoc 的前身是 SmartWiki 文档系统。SmartWiki 是基于 PHP 框架 laravel 开发的一款文档管理系统。因 PHP 的部署对普通用户来说太复杂&#xff0c;所以改用 Golang 开发。可以方便用户部署和实用。 开…

2025寒假备战蓝桥杯01---朴素二分查找的学习

文章目录 1.暴力方法的引入2.暴力解法的思考 与改进3.朴素二分查找的引入4.朴素二分查找的流程5.朴素二分查找的细节6.朴素二分查找的题目 1.暴力方法的引入 对于下面的这个有序的数据元素的组合&#xff0c;我们的暴力解法就是挨个进行遍历操作&#xff0c;一直找到和我们的这…

计算机毕业设计hadoop+spark+hive图书推荐系统 豆瓣图书数据分析可视化大屏 豆瓣图书爬虫 知识图谱 图书大数据 大数据毕业设计 机器学习

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

麒麟操作系统服务架构保姆级教程(十四)iptables防火墙四表五链和防火墙应用案例

如果你想拥有你从未拥有过的东西&#xff0c;那么你必须去做你从未做过的事情 防火墙在运维工作中有着不可或缺的重要性。首先&#xff0c;它是保障网络安全的关键防线&#xff0c;通过设置访问控制规则&#xff0c;可精准过滤非法网络流量&#xff0c;有效阻挡外部黑客攻击、恶…

微服务学习-Nacos 注册中心实战

1. 注册中心的设计思路 1.1. 微服务为什么会用到注册中心&#xff1f; 服务与服务之间调用需要有服务发现功能&#xff1b;例如订单服务调用库存服务&#xff0c;库存服务如果有多个&#xff0c;订单服务到底调用那个库存服务呢&#xff08;负载均衡器&#xff09;&#xff0…

机器人奇点:从宇树科技看2025具身智能发展

近年来&#xff0c;随着人工智能和机器人技术的飞速发展&#xff0c;具身智能&#xff08;Embodied Intelligence&#xff09;逐渐成为科技领域的热门话题。具身智能不仅赋予了机器人感知、决策和执行的能力&#xff0c;还通过与物理世界的交互&#xff0c;推动了人工智能从“离…

Tensor 基本操作1 unsqueeze, squeeze, softmax | PyTorch 深度学习实战

本系列文章 GitHub Repo: https://github.com/hailiang-wang/pytorch-get-started 目录 创建 Tensor常用操作unsqueezesqueezeSoftmax代码1代码2代码3 argmaxitem 创建 Tensor 使用 Torch 接口创建 Tensor import torch参考&#xff1a;https://pytorch.org/tutorials/beginn…

(详细)Springboot 整合动态多数据源 这里有mysql(分为master 和 slave) 和oracle,根据不同路径适配不同数据源

文章目录 Springboot 整合多动态数据源 这里有mysql&#xff08;分为master 和 slave&#xff09; 和oracle1. 引入相关的依赖2. 创建相关配置文件3. 在相关目录下进行编码&#xff0c;不同路径会使用不同数据源 Springboot 整合多动态数据源 这里有mysql&#xff08;分为maste…

03垃圾回收篇(D3_垃圾收集器的选择及相关参数)

目录 学习前言 一、收集器的选择 二、GC日志参数 三、垃圾收集相关的常用参数 四、内存分配与回收策略 1. 对象优先在Eden分配 2. 大对象直接进入老年代 3. 长期存活的对象将进入老年代 4. 动态对象年龄判定 5. 空间分配担保 学习前言 本章主要学习垃圾收集器的选择及…

Hadoop特点和HDFS命令

Hadoop的特点 高扩展性: 可以根据数据量的增长进行扩展,可以扩展到数千台机器&#xff0c;每个机器都可以提供本地计算和存储资源 高容错性: 自动保存数据的多个副本&#xff0c;并能够在硬件故障的情况下重新分配计算任务&#xff0c;从而确保系统的高可用性和数据的不丢失。…

LetsWave脑电数据简单ERP分析matlab(一)

LetsWave是基于matlab的一款工具包&#xff0c;类似eeglab&#xff0c;也可以对数据进行预处理。习惯使用eeglab做数据预处理的&#xff0c;可以先在eeglab中做预处理&#xff0c;然后可以保存为*.set格式&#xff0c;最后在letswave中画图。 letswave下载地址&#xff1a;htt…

深度学习|表示学习|卷积神经网络|通道 channel 是什么?|05

如是我闻&#xff1a; 在卷积神经网络&#xff08;CNN&#xff09;中&#xff0c;channel&#xff08;通道&#xff09; 是指输入或输出数据的深度维度&#xff0c;通常用来表示输入或输出的特征类型。 通道的含义 输入通道&#xff08;Input Channels&#xff09;&#xff1a;…