
M1启动是指将内存中的 *** 作系统(OS)加载到处理器中,从而使处理器能够对其进行指令 *** 作。M2启动是指将设备驱动程序(也称为装载程序)加载到内存中,以便处理器能够控制硬件设备。M3启动是指将用户定义的应用程序加载到内存中,以便处理器能够 *** 作它们。
M1启动是必须的,因为 *** 作系统是硬件与软件之间的桥梁, *** 作系统控制硬件设备的访问,同时负责管理系统资源,以及提供用户界面。M2启动和M3启动是可选的,可以根据用户需要决定是否加载它们。M2启动提供外部设备的支持,如显示器,硬盘,打印机和网络设备,以便处理器能够控制它们。M3启动提供应用程序的支持,以便处理器能够 *** 作它们,如文字处理程序,游戏,编程语言等。
本文将对Activity的工作过程进行分析。
主要学习以下内容:
(1)系统内部是如何启动一个Activity的
(2)新Activity的对象是何时创建的
(3)Activity的各个生命周日是被系统何时回调的
Activity启动流程分两种,一种是启动正在运行的app的Activity,即启动子Activity。如无特殊声明默认和启动该activity的activity处于同一进程。如果有声明在一个新的进程中,则处于两个进程。另一种是打开新的app,即为Launcher启动新的Activity。后边启动Activity的流程是一样的,区别是前边判断进程是否存在的那部分。
Activity的启动流程整体如下:
一Activity启动阶段
(一)涉及到的概念
进程:Android系统为每个APP分配至少一个进程
IPC:跨进程通信,Android中采用Binder机制。
(二)涉及到的类
ActivityStack:Activity在AMS的栈管理,用来记录已经启动的Activity的先后关系,状态信息等。通过ActivityStack决定是否需要启动新的进程。
ActivitySupervisor:管理 activity 任务栈
ActivityThread:ActivityThread 运行在UI线程(主线程),App的真正入口。
ApplicationThread:用来实现AMS和ActivityThread之间的交互。
ApplicationThreadProxy:ApplicationThread 在服务端的代理。AMS就是通过该代理与ActivityThread进行通信的。
IActivityManager:继承与IInterface接口,抽象出跨进程通信需要实现的功能
AMN:运行在server端(SystemServer进程)。实现了Binder类,具体功能由子类AMS实现。
AMS:AMN的子类,负责管理四大组件和进程,包括生命周期和状态切换。AMS因为要和ui交互,所以极其复杂,涉及window。
AMP:AMS的client端代理(app进程)。了解Binder知识可以比较容易理解server端的stub和client端的proxy。AMP和AMS通过Binder通信。
Instrumentation:仪表盘,负责调用Activity和Application生命周期。测试用到这个类比较多。
(三)涉及到的进程
(1)Launcher所在的进程
(2)AMS所在的SystemServer进程
(3)要启动的Activity所在的app进程
如果是启动根Activity,就涉及上述三个进程。
如果是启动子Activity,那么就只涉及AMS进程和app所在进程。
(四)具体流程
Launcher:Launcher通知AMS要启动activity。
startActivitySafely->startActivity->InstrumentationexecStartActivity()(AMPstartActivity)->AMSstartActivity
AMS:PMS的resoveIntent验证要启动activity是否匹配。如果匹配,通过ApplicationThread发消息给Launcher所在的主线程,暂停当前Activity(即Launcher)。
暂停完,在该activity还不可见时,通知AMS,根据要启动的Activity配置ActivityStack。然后判断要启动的Activity进程是否存在
存在:发送消息LAUNCH_ACTIVITY给需要启动的Activity主线程,执行handleLaunchActivity
不存在:通过socket向zygote请求创建进程。进程启动后,ActivityThreadattach
判断Application是否存在,若不存在,通过LoadApkmakeApplication创建一个。在主线程中通过threadattach方法来关联ApplicationThread。
在通过ActivityStackSupervisor来获取当前需要显示的ActivityStack。
继续通过ApplicationThread来发送消息给主线程的Handler来启动Activity (handleLaunchActivity)。
handleLauchActivity:调用了performLauchActivity,里边Instrumentation生成了新的activity对象,继续调用activity生命周期。
IPC过程:
双方都是通过对方的代理对象来进行通信。
1app和AMS通信:app通过本进程的AMP和AMS进行Binder通信
2AMS和新app通信:通过ApplicationThreadProxy来通信,并不直接和ActivityThread通信
(五)参考函数流程
Activity启动流程(从Launcher开始):
第一阶段: Launcher通知AMS要启动新的Activity(在Launcher所在的进程执行)
第二阶段:AMS先校验一下Activity的正确性,如果正确的话,会暂存一下Activity的信息。然后,AMS会通知Launcher程序pause Activity(在AMS所在进程执行)
第三阶段:pause Launcher的Activity,并通知AMS已经paused(在Launcher所在进程执行)
第四阶段:检查activity所在进程是否存在,如果存在,就直接通知这个进程,在该进程中启动Activity;不存在的话,会调用Processstart创建一个新进程(执行在AMS进程)
第五阶段: 创建ActivityThread实例,执行一些初始化 *** 作,并绑定Application。如果Application不存在,会调用LoadedApkmakeApplication创建一个新的Application对象。之后进入Loop循环。(执行在新创建的app进程)
第六阶段:处理新的应用进程发出的创建进程完成的通信请求,并通知新应用程序进程启动目标Activity组件(执行在AMS进程)
第七阶段: 加载MainActivity类,调用onCreate声明周期方法(执行在新启动的app进程)
从另一个角度下图来概括:
下面简要介绍一下启动的过程:
Step 1 无论是通过Launcher来启动Activity,还是通过Activity内部调用startActivity接口来启动新的Activity,都通过Binder进程间通信进入到ActivityManagerService进程中,并且调用ActivityManagerServicestartActivity接口;
Step 2 ActivityManagerService调用ActivityStackstartActivityMayWait来做准备要启动的Activity的相关信息;
Step 3 ActivityStack通知ApplicationThread要进行Activity启动调度了,这里的ApplicationThread代表的是调用ActivityManagerServicestartActivity接口的进程,对于通过点击应用程序图标的情景来说,这个进程就是Launcher了,而对于通过在Activity内部调用startActivity的情景来说,这个进程就是这个Activity所在的进程了;
Step 4 ApplicationThread不执行真正的启动 *** 作,它通过调用ActivityManagerServiceactivityPaused接口进入到ActivityManagerService进程中,看看是否需要创建新的进程来启动Activity;
Step 5 对于通过点击应用程序图标来启动Activity的情景来说,ActivityManagerService在这一步中,会调用startProcessLocked来创建一个新的进程,而对于通过在Activity内部调用startActivity来启动新的Activity来说,这一步是不需要执行的,因为新的Activity就在原来的Activity所在的进程中进行启动;
Step 6 ActivityManagerServic调用ApplicationThreadscheduleLaunchActivity接口,通知相应的进程执行启动Activity的 *** 作;
Step 7 ApplicationThread把这个启动Activity的 *** 作转发给ActivityThread,ActivityThread通过ClassLoader导入相应的Activity类,然后把它启动起来。
WMS作为系统的一个关键服务其是在SystemServerjava::startOtherServices中启动的
WMS主要有下面几个作用:
1:应用程序通过WMS向SurfaceFinger申请surface,surface代表的是绘图表面,应用程序绘制都必须在绘图表面上
2:管理窗口的层级,一个窗口一般在WMS端都是一个WindowState,其是有层级区分的,其有baseLayer和subLayer两个值共同确定
3:窗口动画:WindowAnimator
其中上面有一个比较重要的对象PhoneWindowManager,主要是负责窗口管理的各种策略
AMS,WMS之间数据是对应的,通过token值可以在AMS,WMS,应用程序之后来唯一确定一组Window,token是关联着一组窗口的,可能有多个WindowState的token值是相同的
整个启动过程涉及3个线程: system_server主线程, “androiddisplay”, “androidui”, 整个过程是采用阻塞方式(利用HandlerrunWithScissors)执行的 其中WindowManagerServicemH的Looper运行在 “androiddisplay”进程,也就意味着WMSHhandleMessage()在该线程执行。
开发中我们会调用startActivity来启动一个Activity,最终会调到 startActivityForResult :
Instrumentation 是Android系统里面的一套控制方法或者“钩子”。这些钩子可以在正常的生命周期(正常是由 *** 作系统控制的)之外控制Android控件的运行。
Application和Activity的所有生命周期中,都会先调用Instrumentation提供的相应方法(如callActivityOnCreate,callApplicationOnCreate,newActivity,callActivityOnNewIntent)
InstrumentationexecStartActivity
ActivityTaskManagergetService()返回了一个IActivityTaskManager,拿到的是ATMS的代理对象,跨进程调用了ATMS的startActivity方法。
ActivityStarterstartActivityMayWait
ActivityStarter中做了一系列的调用(收集Intent信息,处理startActivityForResult,做一些校验判断等),最终进入startActivityUnchecked。
startActivityUnchecked
startActivityUnchecked中处理了关于Activity启动模式的处理,接着真正的resume我们的Activity
这里会先判断应用进程是否创建,创建了就进入 realStartActivityLocked ,没创建就会调用 ActivityManagerInternalstartProcess
①热启动realStartActivityLocked
接着看ActivityThread中接收并处理消息的handleMessage
前面realStartActivityLocked方法中通过addCallback,传入参数LaunchActivityItem。executeCallbacks方法中取出callbacks集合中的LaunchActivityItem,并调用其execute方法
handleLaunchActivity
②冷启动创建应用进程ActivityManagerInternalstartProcess
ActivityManagerInternal的实现类是AMS中的LocalService,AMS通过Socket与Zygote通信,fork出App进程,app进程创建后,会执行ActivityThread的main方法(Android进程入口方法)
调用ActivityThread的attach
[4]threadbindApplication 这是一个binder通信的过程
ActivityThread内部的Handler接收到BIND_APPLICATION消息
回到上面attachApplicationLocked的mAtmInternalattachApplication,调用ATMS的attachApplication
看到了似曾相识的realStartActivityLocked,后面流程和之前一样。Activity启动流程分析完毕。
总结
1)与Activity管理有关的类:
ActivityRecord :历史栈中的一个条目,代表一个Activity
TaskRecord :内部维护了一个ArrayList<ActivityRecord> ,来保存ActivityRecord
ActivityStack :内部维护了一个ArrayList<TaskRecord>,用来管理TaskRecord
ActivityStackSupervisor :用来管理ActivityStack的
2)Activity启动流程
首先贴一张很不错的图,SpringBoot启动结构图,出自SpringBoot启动流程解析。本文的分析基于Spring Boot 215,非Spring的代码只有下面这个启。
提供大量优秀的Web框架方便开发等等。Spring框架具有控制反转(IOC)特性,IOC旨在方便项目维护和测试,它提供了一种通过Java的反射机制对Java对象进行统一的配置和管理的方法。
Spring框架利用容器管理对象的生命周期,容器可以通过扫描XML文件或类上特定Java注解来配置对象,开发者可以通过依赖查找或依赖注入来获得对象。
SpringBoot的启动主要是通过实例化SpringApplication来启动的。
启动过程主要做了以下几件事情:配置属性、获取监听器,发布应用开始启动事件初、始化输入参数、配置环境,输出banner、创建上下文、预处理上下文、刷新上下文(加载tomcat容器)、再刷新上下文、发布应用已经启动事件、发布应用启动完成事件。
在SpringBoot中启动tomcat的工作在刷新上下这一步。
而tomcat的启动主要是实例化两个组件:Connector、Container,一个tomcat实例就是一个Server,一个Server包含多个Service,也就是多个应用程序,每个Service包含多个Connector和一个Container,而一个Container下又包含多个子容器。
嵌入式 Linux 系统从软件角度看可以分为四个部分:引导加载程序(Bootloader), Linux 内核,文件系统,应用程序。
当系统首次引导时,或系统被重置时,处理器会执行一个位于Flash/ROM中的已知位置处的代码,Bootloader就是这第一段代码。它主要用来初始化处理器及外设,然后调用 Linux 内核。Linux 内核在完成系统的初始化之后需要挂载某个文件系统作为根文件系统(Root Filesystem),然后加载必要的内核模块,启动应用程序。这就是嵌入式Linux系统启动过程 Linux 引导的整个过程。
Bootloader 的启动方式:
网络启动方式。这种方式的开发板不需要较大的存储介质,跟无盘工作站有点类似,但是使用这种启动方式之前,需要把Bootloader安装到板上的EPROM或者Flash中。Bootloader通过以太网接口远程下载Linux内核映像或者文件系统。Bootloader下载文件一般都使用TFTP网络协议,还可以通过DHCP的方式动态配置IP地址。
硬盘启动方式
传统的Linux系统运行在台式机或者服务器上,这些计算机一般都使用BIOS引导,并使用磁盘作为存储介质。Linux传统上是LILO (Linux Loader) 引导,后来又出现了GUN的软件 (Grand Unified Bootloader) 。 这两种Bootloader广泛应用在X86的Linux系统上。
Flash启动方式。大多数嵌入式系统上都使用Flash存储介质。Flash有很多类型,包括NOR Flash、NAND Flash和其它半导体盘。它们之间的不同在于: NOR Flash 支持芯片内执行(XIP, eXecute In Place),这样代码可以在Flash上直接执行而不必拷贝到RAM中去执行。而NAND Flash并不支持XIP,所以要想执行 NAND Flash 上的代码,必须先将其拷贝到 RAM中去,然后跳到 RAM 中去执行。NOR Flash 使用最为普遍。Bootloader一般放在Flash的底端或者顶端,这需要根据处理器的复位向量来进行设置。可以配置成MTD设备来访问Flash分区。
以上就是关于分别m1和m2和m3启动全部的内容,包括:分别m1和m2和m3启动、全面解析Activity: Activity的工作过程、WMS 启动流程等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)