Android Activity启动流程刨析

目录
  • 前言
  • 一、Binder的基本理解
  • 二、Activity启动的双向IPC过程
  • 三、AMS服务注册

前言

上篇文章写到 Service 的启动过程; 相对来说Activity的启动过程比Service的启动过程更为复杂,其一Activity的生命周期方法比Service多,其二Activity具有启动模式和返回栈; 写本文的目的在于更清晰的梳理Activity的启动过程,加强自己的内功修炼,力在以最简单的方式让大家理解,跟大家一起学习

一、Binder的基本理解

Activity的启动有多次IPC过程,所以Binder属于预备知识,帮助我们更好理解系统的C/S的这种架构模式

二、Activity启动的双向IPC过程

一般Android各个应用进程的启动都以这样一条路线,init进程 –> Zygote进程 –> SystemServer进程 –>各种应用进程

  • Init进程:Linux的根进程,Android系统是基于Linux系统的,因此可以算作是整个android操作系统的第一个进程;
  • Zygote进程是所有应用进程的父进程,所有的应用进程都是它孵化出来的;
  • SystemServer进程含有一些核心的服务,比如ActivityManagerService,PackageManagerService,WindowManagerService等;
  • 各种应用进程:启动自己编写的客户端应用时,有自己的虚拟机与运行环境。

由此可知应用的第一个Activity的启动是多个进程相互配合的结果,多个进程相互配合就少不了使用Binder进行IPC了,现在看一次IPC调用的过程是怎样的。

上图大概说明了一次IPC的过程,或许你现在对里面各个类还不是很清楚,没关系,大致了解一下

ActivityManagerService (下文简称AMS),AMS是Android中最核心的服务,实现了ActivityManager,主要负责系统中四大组件的启动、切换、调度及应用进程的管理和调度等工作,AMS提供了一个ArrayList mHistory来管理所有的Activity,Activity在AMS中的形式是ActivityRecord,Task在AMS中的形式为TaskRecord,进程在AMS中的管理形式为ProcessRecord,它在Android中特别重要

ActivityManagerNative (下文简称AMN):由于AMS是系统核心服务在SystemServer进程里面,很多API不能直接开放供客户端使用,所以需要通过IPC的方式,具体是这样的,ActivityManager类内部调用AMN的getDefault函数得到一个ActivityManagerProxy对象,通过它可与AMS通信

ActivityManagerProxy (下文简称AMP):AMP是AMS在客户端进程的一个代理,通过AMP里面的方法请求AMS

Instrumentation: Instrumentaion是一个工具类,一个大管家。当它被启用时,系统先创建它,再通过它来创建其他组件;另外,系统和组件之间的交互也将通过Instrumentation来传递,这样,Instrumentation就能监测系统和这些组件的交互情况了。在实际使用中,我们可以创建Instrumentation的派生类来进行相应的处理。Android中Junit的使用到了Intrstrumentation

OK,现在我们知道,Activity是如何向AMS发出startActivity这个请求了,这意味着Activity可以与AMS进行通信,但是AMS却不能与Activity通信,Binder是单向的,所以在Activity发出请求之后,AMS需要通知Activity发生状态改变,要做到这一点,自然就在AMS到Activity这个过程建立一个Binder,如下:

大致过程就是,SystemServer进程在收到请求后,再通过IPC向应用进程发送scheduleLaunchActivity请求,应用进程的binder线程(ApplicationThread)在收到请求后,通过handler向主线程发送LAUNCH_ACTIVITY消息,主线程在收到Message后,创建目标Activity,并回调Activity.onCreate()等方法

对上面的理解不是太明白,在看下面这张图,简单多了;AMS到Activity这个过程建立了一个Binder,Activity到AMS这个过程也建立了一个Binder,这就能相互通信了

上图就是Activity与AMS之间的双向Binder连接, (备注:这个就是理解Activity启动流程的指南针,不记住这个,复杂的启动流程会让你晕头转向);Activity用IActivityManager提供的API向AMS提出执行某个动作的请求(本例中是启动RemoteService),AMS通过IApplicationThread提供的API来控制Activity所在的应用程序,这些API包括schedulePauseActivity()、scheduleStopActivity()等

IActivityManager接口定义的API,启动四大组件的等多种请求都在里面

IApplicationThread接口定义的API,一看就比IActivityManager高逼格一点,IActivityManager好多方法是start开头,表示去AMS请求,IApplicationThread以schedule开头,表示对Activity进行调度

分析到这里,我们不知不觉间忽略了两个问题,那就是启动Activity至少需要两个前提

第一是,应用进程存在,第二AMS已经初始化完毕; 在调用startActivity方法时候,如果我们的应用进程不存在,Activity能启动吗,当然是不能的,比如点击桌面图标的时候,这个时候需要先创建进程。关于Zygote孵化应用进程,这个暂时不说,先看看AMS服务注册

三、AMS服务注册

先忽略 Activity调用ActivityManagerService启动应用,直接从SystemServer的main方法说起

 /**
    * The main entry point from zygote.
    */
   public static void main(String[] args) {
       new SystemServer().run();
   }

run方法中,调用了startBootstrapServices

 private void startBootstrapServices() {
       ......
       //启动AMS服务
       Installer installer = mSystemServiceManager.startService(Installer.class);
       //请注意这里参数是Lifecycle,因为AMS是在Lifecycle里面new出来的
       mActivityManagerService = mSystemServiceManager.startService(
               ActivityManagerService.Lifecycle.class).getService();
       mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
       mActivityManagerService.setInstaller(installer);
       mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
       mActivityManagerService.initPowerManagement();
        ......
       mActivityManagerService.setSystemProcess();
     ......
}
 public SystemService startService(String className) {
       final Class<SystemService> serviceClass;
       try {
           serviceClass = (Class<SystemService>)Class.forName(className);
       } catch (ClassNotFoundException ex) {
           Slog.i(TAG, "Starting " + className);
       }
       return startService(serviceClass);
   }

继续

public <T extends SystemService> T startService(Class<T> serviceClass) {
       try {
           final String name = serviceClass.getName();
           // 1、创建服务
           final T service;
           try {
               Constructor<T> constructor = serviceClass.getConstructor(Context.class);
             // 如果传进来的是ActivityManagerService.Lifecycle对象,那么ActivityManagerService就能被创建
               service = constructor.newInstance(mContext);
           } catch (InstantiationException ex) {
               throw new RuntimeException("Failed to create service " + name
                       + ": service could not be instantiated", ex);
           }
           // 2、注册服务
           mServices.add(service);

           // 3、启动服务
           try {
               service.onStart();
           } catch (RuntimeException ex) {
               throw new RuntimeException("Failed to start service " + name
                       + ": onStart threw an exception", ex);
           }
           return service;
       } finally {
           Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
       }
   }
ActivityManagerService.java
  public static final class Lifecycle extends SystemService {
       private final ActivityManagerService mService;
       public Lifecycle(Context context) {
           super(context);
         //ActivityManagerService被new出来了
           mService = new ActivityManagerService(context);
       }
       @Override
       public void onStart() {
         //  启动
           mService.start();
       }
       public ActivityManagerService getService() {
           return mService;
       }
   }
 private void start() {
       Process.removeAllProcessGroups();
       mProcessCpuThread.start();
       mBatteryStatsService.publish(mContext);
       mAppOpsService.publish(mContext);
       Slog.d("AppOps", "AppOpsService published");
       LocalServices.addService(ActivityManagerInternal.class, new LocalService());
   }

回到 startBootstrapServices里面调用的 mActivityManagerService.setSystemProcess();

public void setSystemProcess() {
       try {
           ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
           ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
           ServiceManager.addService("meminfo", new MemBinder(this));
           ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
           ServiceManager.addService("dbinfo", new DbBinder(this));
           ......
      // 设置application info LoadedApkinfo 有关 framework-res.apk
       ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( "android", STOCK_PM_FLAGS);
       mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
       //给SystemServer进程创建ProcessRecord,adj值,就是将SystemServer进程加入到AMS进程管理机制中,跟应用进程一致
       synchronized (this) {
           ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
           app.persistent = true;
           app.pid = MY_PID;
           app.maxAdj = ProcessList.SYSTEM_ADJ;
           app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
           synchronized (mPidsSelfLocked) {
               mPidsSelfLocked.put(app.pid, app);
           }
           updateLruProcessLocked(app, false, null);
           updateOomAdjLocked();
 }

ServiceManager这里面注册了很多的服务,可通过dumpsys <服务名>命令查看。比如查看CPU信息命令dumpsys cpuinfo,查看graphics信息命令dumpsys gfxinfo

在Android中所有的核心服务,并不是直接给上层使用,都先交给ServiceManager管理,上层使用的时候可以从ServiceManager获取,ServiceManager相当于一个路由作用。现在来看一张经典的图。其中注册服务,获取服务以及使用服务,每一次都是一个完整的Binder IPC过程,可见理解Binder是多么的重要啊。关于AMS启动得深入了解

  • 注册服务:首先AMS注册到ServiceManager。AMS所在进程(SystemServer)是客户端,ServiceManager是服务端
  • 获取服务:Client进程使用AMS前,须先向ServiceManager中获取AMS的代理类AMP。该过程。AMP所在进程(应用进程)是客户端,ServiceManager是服务端
  • 使用服务: app进程根据得到的代理类AMP,便可以直接与AMS所在进程交互。该过程,AMP所在进程(应用进程)是客户端,AMS所在进程(SystemServer)是服务端

到此这篇关于Android Activity启动流程刨析的文章就介绍到这了,更多相关Android Activity 内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Android Activity的生命周期与启动模式全面解读

    目录 Activity概述 Activity生命周期 生命周期的调用顺序 演示 Activity的启动模式 启动模式的设置 standard(默认standard) singleTop singleTask singleInstance Activity概述 • Activity(活动)是Android应用程序中最基本的组成单位. • Activity主要负责创建显示窗口,一个Activity对象通常就代表了一个单独的屏幕. • Activity是用户唯一可以看得到的组件,用来与用户进行交互的.

  • 分析Android Activity的启动过程

    分析Android Activity的启动过程 对于Android Activity 的启动过程,我在Android源码中读了好久的源码,以下是我整理出来的Activity启动过程和大家分享下: Activity作为Android的四大组件之一,也是最基本的组件,负责与用户交互的所有功能.Activity的启动过程也并非一件神秘的事情,接下来就简单的从源码的角度分析一下Activity的启动过程. 根Activity一般就是指我们项目中的MainActivity,代表了一个android应用程序

  • Android Activity的启动过程源码解析

    前言 Activity是Android中一个很重要的概念,堪称四大组件之首,关于Activity有很多内容,比如生命周期和启动Flags,这二者想要说清楚,恐怕又要写两篇长文,更何况分析它们的源码呢.不过本文的侧重点不是它们,我要介绍的是一个Activity典型的启动过程,本文会从源码的角度对其进行分析.我们知道,当startActivity被调用的时候,可以启动一个Activity,但是你知道这个Activity是如何被启动的吗?每个Activity也是一个对象,你知道这个对象是啥时候被创建的

  • 通过实例解析android Activity启动过程

    注:只是说明启动activity的过程(ActivityThread如何与ActivityManagerService简称AmS进行进程间通信调用全过程),不解析android从zygote(受精卵)到整个系统服务的启动 具体来讲,启动activity的方式有以下几种: 在应用程序中startActivity()或startActivityForResult()方法启动指定activity 在HOME(桌面)程序中单击应用图标,启动新的activity 按"BACK"键结束当前acti

  • Android后台启动Activity的实现示例

    目录 概述 原生Android ROM 定制化ROM 检测后台弹出界面权限 Android P后台启动权限 Android Q后台启动权限 总结 概述 前几天产品提了一个需求,想在后台的时候启动我们 APP 的一个 Activity,随着 Android 版本的更新,以及各家 ROM 厂商的无限改造,这种影响用户体验的功能许多都受到了限制,没办法,虽然是比较流氓的功能,但拿人钱财替人消灾,于是开启了哼哧哼哧的调研之路. 原生Android ROM 首先从 Android 的原生 ROM 开始,根

  • Android 启动另一个App/apk中的Activity实现代码

    Android 启动另一个App/apk中的Activity实现代码 前言: Android提供了在一个App中启动另一个App中的Activity的能力,这使我们的程序很容易就可以调用其他程序的功能,从而就丰富了我们App的功能.比如在微信中发送一个位置信息,对方可以点击这个位置信息启动腾讯地图并导航.这个场景在现实中作用很大,尤其是朋友在陌生的环境找不到对方时,这个功能简直就是救星. 本来想把本文的名字叫启动另一个进程中的Activity,觉得这样才有逼格.因为每个App都会运行在自己的虚拟

  • Android Activity的4种启动模式图文介绍

    前言 记得第一次探讨Activity的启动模式,是在2017年8月份,那个时候对一年后走出校门的未来很是憧憬,时间真快,已经毕业四个月,工作和生活也都趋于稳定. 一.小前言 相信很多人和我一样,在初学Android甚至初入职场的时候不了解Acticity的启动模式,或者为了面试刷题刷到了,但并不理解启动模式的作用,以及如何正确的使用启动模式而不是所有的都是用默认模式. 二.Activity启动模式简介 Activity有四种启动模式,standard.singleTop.singleTask.s

  • 详解Android Activity的启动流程

    前言 activity启动的流程分为两部分:一是在activity中通过startActivity(Intent intent)方法启动一个Activity:二是我们在桌面通过点击应用图标启动一个App然后显示Activity:第二种方式相较于第一种方式更加全面,所以本文会以第二种流程来分析. 简要 我们手机的桌面是一个叫做Launcher的Activity,它罗列了手机中的应用图标,图标中包含安装apk时解析的应用默认启动页等信息.在点击应用图标时,即将要启动的App和Launcher.AMS

  • Android中Activity的四种启动模式和onNewIntent()

    写在前面 Activity是Android四大组件之一,用于直接跟用户进行交互,本篇文章将介绍Activity的启动流程.用户启动Activity的方式大致有两种:一种是在桌面点击应用程序的图标,进入应用程序的主界面:另一种是在应用程序中,进入一个新的Activity.前者,桌面其实是系统应用launcher的界面,点击应用程序图标,会进行应用程序的主界面,实质是从一个应用的Activity进入另一个应用Activity. 因此,不管是从桌面进入应用主界面,还是在应用里进入一个新的Activit

  • Android Activity启动流程刨析

    目录 前言 一.Binder的基本理解 二.Activity启动的双向IPC过程 三.AMS服务注册 前言 上篇文章写到 Service 的启动过程: 相对来说Activity的启动过程比Service的启动过程更为复杂,其一Activity的生命周期方法比Service多,其二Activity具有启动模式和返回栈: 写本文的目的在于更清晰的梳理Activity的启动过程,加强自己的内功修炼,力在以最简单的方式让大家理解,跟大家一起学习 一.Binder的基本理解 Activity的启动有多次I

  • Android Service启动流程刨析

    强调一下阅读系统源码,起码要对进程间通信要了解,对binder机制非常非常清楚,binder就是指南针,要不然你会晕头转向:强行阅读,就容易睡着. Service启动先来一张图感受一下 这张图能够说明一个大致的流程,但是服务的启动肯定不是这么简单,但是我们先简单的总结一下,逐渐深入.服务的启动形式有两种,startService()和 binderService(),我们看startService()这一种.startService是ContextWrapper里面的方法. ContextWra

  • 一文带你看懂Android Application启动流程是怎样的

    基于Android11-API30 总览 获取applicationThread,AMS这两个Binder2.attach时,将获取applicationThread对象也传递到AMS进程,请求远程调用通知AMS应用进程想要创建Application,此时AMS为服务端 AMS收到消息,请求调用applicationThread的远程接口,此时AMS为客户端 applicationThread收到AMS的请求,通过Handler发起创建Application的处理任务,后面就没有远程接口调用了

  • Framework源码面试之activity启动流程

    目录 引言 Framework源码面试:activity启动流程 1.1面试连环炮之说说 Android 的四种启动模式 1.2.面试连环炮之说说 Intent标签起什么作用呢? 简单说一说 1.2.Android 的启动原理,他的流程是什么样的 1.2.1.进程A与AMS的交互过程 引言 今天在电脑上翻出了很久之前整理笔记Framework源码面试,Flutter,以及一部分面试专题.拿出来温习一下. 今天先讲Framework源码篇: 1.Framework源码面试:Activity启动流程

  • Android Activity启动模式之standard实例详解

    本文实例讲述了Android Activity启动模式之standard.分享给大家供大家参考,具体如下: Android的活动是通过任务Task来进行管理的,一个任务就是一组放在栈里的活动的集合,即所谓的返回栈(Back Stack).栈具有先进后出.后进先出的特性.当启动一个活动时,活动会在返回栈中入栈,处于栈顶位置,当按下返回键或者调用finish方法会销毁一个活动,此时栈顶活动会出栈,届时又会有新的活动处于栈顶位置. 在Android中,活动的启动模式有四种,根据不同的需求可以为活动设置

  • Android Activity启动模式之singleTask实例详解

    本文实例分析了Android Activity启动模式之singleTask.分享给大家供大家参考,具体如下: 前面的文章介绍了Android 活动Activity的启动模式:standard 和singleTop .本文继续介绍Activity的下一个启动模式:singleTask. singleTask:当设置活动的启动模式为singleTask时,首先检查返回栈中是否存在当前活动,如果存在当前活动的实例,则直接使用当前实例,并把当前活动之上的所有活动pop出栈,即当前活动位于栈顶位置. 代

  • Android Activity启动模式之singleTop实例详解

    本文实例讲述了Android Activity启动模式之singleTop.分享给大家供大家参考,具体如下: 在前面文章<Android Activity启动模式之standard实例详解>中,我们介绍了活动的默认启动模式standard,本文继续介绍Activity的singleTop模式. singleTop模式:当Activity的活动模式设置为singleTop时,在启动活动时首先检查栈顶活动是否是该活动,如果是,在使用当前实例,否则继续创建新的实例. (1)修改AndroidMani

  • Android zygote启动流程详解

    对zygote的理解 在Android系统中,zygote是一个native进程,是所有应用进程的父进程.而zygote则是Linux系统用户空间的第一个进程--init进程,通过fork的方式创建并启动的. 作用 zygote进程在启动时,会创建一个Dalvik虚拟机实例,每次孵化新的应用进程时,都会将这个Dalvik虚拟机实例复制到新的应用程序进程里面,从而使得每个应用程序进程都有一个独立的Dalvik虚拟机实例. zygote进程的主要作用有两个: 启动SystemServer. 孵化应用

  • Android ActivityManagerService启动流程详解

    目录 概述 AMS的启动流程 启动流程图 概述 AMS是系统的引导服务,应用进程的启动.切换和调度.四大组件的启动和管理都需要AMS的支持.从这里可以看出AMS的功能会十分的繁多,当然它并不是一个类承担这个重责,它有一些关联类. AMS的启动流程 1:SystemServer#main -> 2:SystemServer#run -> 3:SystemServiceManager#startBootstrapServices 1:首先SystemServer进程运行main函数, main函数

  • 详解Android.activity销毁流程的工作原理

    继续我们的源码解析,上一篇文章我们介绍了Activity的启动流程,一个典型的场景就是Activity a 启动了一个Activity b,他们的生命周期回调方法是: onPause(a) –> onCreate(b) –> onStart(b) –> onResume(b) –> onStop(a) 而我们根据源码也验证了这样的生命周期调用序列,那么Activity的销毁流程呢?它的生命周期的调用顺序又是这样的呢? 这里我们我做一个简单的demo,让一个Activity a启动A

随机推荐