当前位置: 首页 > article >正文

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的启动流程。


http://www.kler.cn/a/518481.html

相关文章:

  • 第二十一周:Mask R-CNN
  • 82,【6】BUUCTF WEB .[CISCN2019 华东南赛区]Double Secret
  • 微信小程序-点餐(美食屋)02开发实践
  • Vue.js组件开发-如何实现带有搜索功能的下拉框
  • 小识Java死锁是否会造成CPU100%?
  • 蓝桥杯算法赛第25场月赛
  • “AI视觉贴装系统:智能贴装,精准无忧
  • 《论文翻译》KIMI K1.5:用大语言模型扩展强化学习
  • 保存复合型数据到h5文件
  • ptp同步时钟、ptp网络时间服务器、ptp主时钟、ptp从时钟、ptp精密同步时钟
  • 15 分布式锁和分布式session
  • ElasticSearch JavaRestClient查询之快速入门
  • antdesignvue统计数据源条数、计算某列合计值、小数计算不精确多了很多小数位
  • 媒体新闻发稿要求有哪些?什么类型的稿件更好通过?
  • navicat无法连接虚拟机的docker中的mysql
  • 理解C++编译时类型转换符:static_cast
  • 系统思考—复杂问题的根源分析
  • 技术之翼,创作之心
  • Java设计模式 十 装饰模式 (Decorator Pattern)
  • 2025,“鱿鱼游戏”闯入AI赛道
  • MySql精确匹配“,“分隔开的内容的函数语法
  • 探索Python GUI新选择:Flet库介绍与快速实践
  • Leetcode热题——移动零
  • [STM32 - 野火] - - - 固件库学习笔记 - - -十一.电源管理系统
  • ELK环境搭建
  • 在K8S中,如果后端NFS存储的IP发送变化如何解决?