当前位置:   article > 正文

Android——APP启动流程&&Android开机流程_安卓app 启动 顺序

安卓app 启动 顺序

1.APP启动流程

在这里插入图片描述
启动流程:

  • ①点击桌面App图标,Launcher进程采用Binder IPC向system_server进程发起startActivity请求;
  • ②system_server进程接收到请求后,向zygote进程发送创建进程的请求;
  • ③Zygote进程fork出新的子进程,即App进程;
  • ④App进程,通过Binder IPC向sytem_server进程发起attachApplication请求;
  • ⑤system_server进程在收到请求后,进行一系列准备工作后,再通过binder IPC向App进程发送scheduleLaunchActivity请求;
  • ⑥App进程的binder线程(ApplicationThread)在收到请求后,通过handler向主线程发送LAUNCH_ACTIVITY消息;
  • ⑦主线程在收到Message后,通过发射机制创建目标Activity,并回调Activity.onCreate()等方法。
  • ⑧到此,App便正式启动,开始进入Activity生命周期,执行完onCreate/onStart/onResume方法,UI渲染结束后便可以看到App的主界面

1. Android开机流程

在这里插入图片描述

  • BootLoader引导:
    当按开机键的时候,引导芯片开始从固化在ROM的预设代码开始执行,然后加载引导程序到RAM
    BootLoader,又称为引导程序。它是在操作系统运行之前运行的一段程序
    BootLoader负责初始化软件运行所需要的最小硬件环境,最后加载内核到内存

  • 启动Kernel:
    这个入口的函数是start_kernel函数
    start_kernel函数执行到最后调用了reset_init函数进行后续的初始化
    start_kernel最终启动用户空间的init程序

  • 启动Android:
    当初始化内核之后,init进程负责解析init.rc配置文件, 就会启动一个相当重要的祖先进程,也就是init进程,在Linux中所有的进程都是由init进程直接或间接fork出来的

* /system/bin/app_process_Zygote服务启动的进程名
* --start-system-server 表明Zygote启动完成后,需要启动System_Server进程
* socket zygote stream 666Zygote启动时,创建一个权限为666的socket。此socket用来请求zygote创建新进程
* socket的fd保存在名称为"ANDROID_SOCKET_zygote"的环境变量中
  • 1
  • 2
  • 3
  • 4

init进程负责创建系统中最关键的几个核心daemon(守护)进程,尤其是zygote和System_Server进程

1. zygote进程 android启动的第一个Dalvik 虚拟机,它将负责启动Java世界的进程
2. zygote虚拟机启动子进程system_server,同时也可以看出zygote中定义了一个Socket,绑定666端口,用于接收ActivityManagerService启动应用程序的请求
3. System_Server进程  Binder通信的基础,它还提供了property service(属性服务),类似于windows系统的注册表服务
4. 系统里面重要的服务都是在这个进程里面开启的,例如AMS, WindowsManager, PackageManagerService等等都是由这个System_Server fork出来的
5.System_Server进程开启的时候,就会初始化ActivityManagerService 。同时,会加载本地系统的服务库,调用createSystemContext()创建系统上下文,创建ActivityThread及开启各种服务等等
6. system_server中开启了核心系统服务,并将系统服务添加到ServiceManager中,然后系统进入SystemReady状态
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 启动Home Activity:
    • 1.在systemReady状态,ActivityManagerService会与zygote的Socket通信,请求启动Home
    • 2.zygote收到AMS的连接请求后,执行runSelectLoopMode处理请求
    • 3.zygote处理请求会通过forkAndSpecialize启动新的应用进程,并最终启动Home
概况
1. 系统加电,执行bootloader。Bootloader负责初始化软件运行的最小硬件环境,最后加载内核到内存
2. 内核加载到内存后,进入内核引导阶段,在内核引导的最后,调用start_kernel进入内核启动阶段。start_kernel最终启动用户空间的init程序
3. init负责解析init.rc配置文件,开启系统守护进程。2个最重要的守护进程是zygote进程和serverManager进程。zygote是android启动的第一个Dalvik虚拟机,ServiceManager服务是Binder通信的基础
4. zygote虚拟机启动子进程system_server,在system_server中启动了核心系统服务,并将系统服务添加到ServiceManager中,然后系统进入SystemReady状态
5.SystemReady状态,ActivityManagerService与zygote中的socket通信,通过zygote启动home应用,进入系统界面
 
* 从步骤3开始, init启动后,上层的实现
1. init启动的核心Daemon服务包括Android的第一个Dalvik虚拟机Zygote
2. zygote定义一个socket,用于接受ActivityManangerService启动应用的请求
3. zygote通过fork系统调用创建system_server进程
4. 在system_server进程中,将会启动系统核心服务以及其他服务
5. 系统服务启动后会注册到ServiceManager中,用于Binder通信
6. ActivityManagerService进入systemReady状态
7. 在systemReady状态,ActivityManangerService会与zygote的Socket通信,请求启动Home
8. zygote收到AMS的连接请求后,执行runSelectLoopMode处理请求
9. zygote处理请求会通过forkAndSpecialize启动新的应用进程,并最终启动Home
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

2. 理论解释

(1)zygote

Android是基于Linux系统的,而在Linux中,所有的进程都是由init进程直接或者是间接fork出来的,zygote进程也不例外。

我们都知道,每一个App其实都是

  • 一个单独的dalvik虚拟机
  • 一个单独的进程

Dalvik虚拟机:

  • Dalvik是Google公司自己设计用于Android平台的Java虚拟机,它是Android平台的重要组成部分,支持dex格式(Dalvik Executable)的Java应用程序的运行
  • Dalvik作为面向Linux、为嵌入式操作系统设计的虚拟机,主要负责完成对象生命周期管理、堆栈管理、线程管理、安全和异常管理,以及垃圾回收等
  • 所有的Android程序都运行在Android系统进程里,每个进程对应着一个Dalvik虚拟机实例。

系统里面的第一个zygote进程运行之后,在这之后再开启App,就相当于开启一个新的进程。而为了实现资源共用和更快的启动速度,Android系统开启新进程的方式,是通过fork第一个zygote进程实现的。

所以说,除了第一个zygote进程,其他应用所在的进程都是zygote的子进程

(2)system_server

  • SystemServer也是一个进程,而且是由zygote进程fork出来的。这个进程是AndroidFramework里面两大非常重要的进程之一——另外一个进程就是上面的zygote进程。
  • 系统里面重要的服务都是在这个进程里面开启的,比如 ActivityManagerService、PackageManagerService、WindowManagerService等等。

(3)ActivityManagerService

  • ActivityManagerService,简称AMS,服务端对象,负责系统中所有Activity的生命周期。
  • ActivityManagerService进行初始化的时机很明确,就是在SystemServer进程开启的时候,就会初始化ActivityManagerService。

Android系统里面的服务器和客户端

  • 其实服务器客户端的概念不仅仅存在于Web开发中,在Android的框架设计中,使用的也是这一种模式
  • 服务器端指的就是所有App共用的系统服务,比如我们这里提到的ActivityManagerService,和前面提到的PackageManagerService、WindowManagerService等等,比如你想打开一个App,那么我们知道了包名和MainActivity类名之后就可以打开
	Intent intent = new Intent(Intent.ACTION_MAIN);
	intent.addCategory(Intent.CATEGORY_LAUNCHER);
	ComponentName cn = new ComponentName(packageName, className);
	
	intent.setComponent(cn);
	startActivity(intent);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

但是,我们的App通过调用startActivity()并不能直接打开另外一个App,这个方法会通过一系列的调用,最后还是告诉AMS说:“我要打开这个App,我知道他的住址和名字,你帮我打开吧!

所以是AMS来通知zygote进程来fork一个新进程,来开启我们的目标App的。这就像是浏览器想要打开一个超链接一样,浏览器把网页地址发送给服务器,然后还是服务器把需要的资源文件发送给客户端的。

App,AMS(SystemServer进程)还有zygote进程如何通信:

  • 他们分属于三个独立的进程
  • App与AMS通过Binder进行IPC通信,AMS(SystemServer进程)与zygote通过Socket进行IPC通信

AMS有什么用?

  • 如果想打开一个App的话,需要AMS去通知zygote进程
  • 所有的Activity的开启、暂停、关闭都需要AMS来控制,所以我们说,AMS负责系统中所有Activity的生命周期
  • 在Android系统中,任何一个Activity的启动都是由AMS和应用程序进程(主要是ActivityThread)相互配合来完成的。AMS服务统一调度系统中所有进程的Activity启动,而每个Activity的启动过程则由其所属的进程具体来完成。

(4)Launcher

当我们点击手机桌面上的图标的时候,App就由Launcher开始启动了。但是,你有没有思考过Launcher到底是一个什么东西?

  • Launcher本质上也是一个应用程序,和我们的App一样,也是继承自Activity
  • Launcher实现了点击、长按等回调接口,来接收用户的输入

(5)Instrumentation和ActivityThread

  • 每个Activity都持有Instrumentation对象的一个引用,但是整个进程只会存在一个Instrumentation对象
  • Instrumentation这个类里面的方法大多数和Application和Activity有关,这个类就是完成对Application和Activity初始化和生命周期的工具类,对Activity生命周期方法的调用根本就离不开这个类
  • ActivityThread,依赖于UI线程
  • App和AMS是通过Binder传递信息的,那么ActivityThread就是专门与AMS的外交工作的

(6)ApplicationThread

前面我们已经知道了App的启动以及Activity的显示都需要AMS的控制,那么我们便需要和服务端的沟通,而这个沟通是双向的。

客户端–>服务端:在这里插入图片描述
由于继承了同样的公共接口类,ActivityManagerProxy提供了与ActivityManagerService一样的函数原型,使用户感觉不出Server是运行在本地还是远端,从而可以更加方便的调用这些重要的系统服务。

服务端–>客户端:
还是通过Binder通信,不过是换了另外一对,换成了ApplicationThread和ApplicationThreadProxy。
在这里插入图片描述
他们也都实现了相同的接口IApplicationThread

	private class ApplicationThread extends ApplicationThreadNative
	{}
	
	public abstract class ApplicationThreadNative extends Binder implements IApplicationThread{}
	
	class ApplicationThreadProxy implements IApplicationThread {}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

3. 启动流程详解

(1)创建进程

在这里插入图片描述

  • ①App发起进程:当从桌面启动应用,则发起进程便是Launcher所在进程;当从某App内启动远程进程,则发送进程便是该App所在进程。发起进程先通过binder发送消息给system_server进程
  • ②system_server进程:调用Process.start()方法,通过socket向zygote进程发送创建新进程的请求;
  • ③zygote进程:在执行ZygoteInit.main()后便进入runSelectLoop()循环体内,当有客户端连接时便会执行ZygoteConnection.runOnce()方法,再经过层层调用后fork出新的应用进程;
  • ④新进程:执行handleChildProc方法,最后调用ActivityThread.main()方法。

(2)绑定Application

在这里插入图片描述

  • 上面创建进程后,执行ActivityThread.main()方法
  • 随后调用attach()方法。将进程和指定的Application绑定起来。通过上节的ActivityThread对象中调用bindApplication()方法完成的。该方法发送一个BIND_APPLICATION的消息到消息队列中
  • 最终通过handleBindApplication()方法处理该消息. 然后调用makeApplication()方法来加载App的classes到内存中。

(3)显示Activity界面

经过前两个步骤之后, 系统已经拥有了该application的进程。 后面的调用顺序就是普通的从一个已经存在的进程中启动一个新进程的activity了。
在这里插入图片描述

  • 实际调用方法是realStartActivity(), 它会调用application线程对象中的scheduleLaunchActivity()发送一个LAUNCH_ACTIVITY消息到消息队列中, 通过handleLaunchActivity()来处理该消息。
  • 在 handleLaunchActivity()通过performLaunchActiivty()方法回调Activity的onCreate()方法和onStart()方法,然后通过handleResumeActivity()方法,回调Activity的onResume()方法,最终显示Activity界面。

(4)Binder通信

在这里插入图片描述
简称:
-ATP: ApplicationThreadProxy

  • AT: ApplicationThread
  • AMP: ActivityManagerProxy
  • AMS: ActivityManagerService
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/672281
推荐阅读
相关标签
  

闽ICP备14008679号