Android手机从开机到APP启动通过的流程

版权声明:转载请务必注明做者与原文连接java

引言

本文讲解从开机到app显示画面的流程,但不分析源码,若是想阅读源码请到参考文章中查阅。android

本文把这段流程分为三部分:git

  • 从开机到显示应用列表
  • 从点击应用图标到Activity建立成功
  • 从Activity建立成功到显示画面

从开机到显示应用列表

先看流程图: 编程

开机加电后,CPU先执行预设代码、加载ROM中的引导程序Bootloader和Linux内核到RAM内存中去,而后初始化各类软硬件环境、加载驱动程序、挂载根文件系统,执行init进程canvas

init进程会启动各类系统本地服务,如SM(ServiceManager)、MS(Media Server)、bootanim(开机动画)等,而后init进程会在解析init.rc文件后fork()出Zygoto进程服务器

Zygote会启动Java虚拟机,经过jni进入Zygote的java代码中,并建立socket实现IPC进程通信,而后启动SS(SystemServer)进程。网络

SS进程负责启动和管理整个framework,包括AMS(ActivityManagerService)、WMS(WindowManagerService)、PMS(PowerManagerService)等服务、同时启动binder线程池,当SS进程将系统服务启动就绪之后,就会通知AMS启动Home。多线程

AMS经过Intent隐式启动的方式启动Launcher,Launcher根据已安装应用解析对应的xml、经过findBiewById()得到一个RecycleView、加载应用图标、最后成功展现App列表。app

解释

  • 预设代码:cpu制造厂商会预设一个地址,这个地址是各厂家约定统一的,Android手机会将固态存储设备ROM预先映射到该地址上;
  • Bootloader:相似BIOS,在系统加载前,用以初始化硬件设备,创建内存空间的映像图,为最终调用系统内核准备好环境;
  • init进程:init进程时Android系统中用户进程的鼻祖进程,主要做用是启动系统本地服务、fork出Zygoto进程;
  • SM:ServiceManager是一个守护进程,它维护着系统服务和客户端的binder通讯;
  • Zygoto进程:Zygoto进程是全部Java进程的父进程,咱们的APP都是由Zygoto进程fork出来的;
  • socket:一种独立于协议用于两个应用程序之间的数据传输的网络编程接口,是IPC中的一种;(可是在Android中通常使用Binder来实现IPC,这里使用socket的缘由后面有写到)
  • SS:Framework两大重要进程之一(另外一个是Zygote),载着framework的核心服务,系统里面重要的服务都是SS开启的;
  • AMS:服务端对象,负责系统中全部Activity的生命周期,打开App、Activity的开启、暂停、关闭都须要AMS来控制;
  • WMS:窗口管理服务,窗口的启动、添加、删除、大小、层级都是由WMS管理;(下面会解释什么是窗口)
  • Launcher:Launcher就是系统桌面,主要用来启动应用桌面,同时管理快捷方式和其余组件,本质上也是一个应用程序,和咱们的App同样,也是继承自Activity,有本身的AndroidManifest;(因此才能够被AMS用Intent启动)

Question 1: Zygote进程为何使用Socket而不是Binder? fork不容许存在多线程,而Binder通信恰巧就是多线程;socket

Question 2:什么是窗口? Android系统中的窗体是屏幕上的一块用于绘制各类UI元素并可以响应应用户输入的一个矩形区域,从原理上来说,窗体的概念是独自占有一个Surface实例的显示区域,好比Dialog、Activity的界面、壁纸、状态栏以及Toast等都是窗体;

从点击应用图标到Activity建立成功

先看流程图:

//而后点击应用图标后,先检查要打卡的Activity是否存在
--> Launcher.startActivitySafely()
--> Launcher.startActivity()
--> Activity.startActivity()
--> Activity.startActivityForResult()

//而后获取AMS的代理AMP
--> Instrumentation.execStartActivity()
--> ActivityManagerNative.getDefault().startActivity()
--> ActivityManagerProxy.startActivity()
--> ActivityManagerService.startActivity()
--> startActivityAsUser(intent, requestCode, userId)
--> ActivityStackSupervisor.startActivityMayWait()
--> ActivityStackSupervisor.resolveActivity()
--> ActivityStackSupervisor.startActivityLocked()
--> new ActivityRecord对象,获取ActivityStack
--> 找到ActivityStack后Launcher.onPause()

//准备启动进程
--> ActivityManagerService.startProcessLocked()
//经过socket通知Zygote建立进程
--> zygoteSendArgsAndGetResult()
//建立ActivityThread
--> ActivityThread.main()
//告诉AMS我已经建立好了
--> ActivityThread.attach()
--> ActivityManagerProxy.attachApplication()
--> ActivityMangerService.attachApplication()
//找到Application实例并初始化
--> ActivityMangerService.attachApplicationLocked()

--> ApplicationThread.bindApplication()
//建立Application
--> AcitvityThread.bindApplication()
--> Application.oncreate()

//启动Activity
--> ActivityStackSupervisor.attachApplicationLocked()
--> ActivityStackSupervisor.realStartActivityLocked()
--> ActivityThread.scheduleLaunchActivity()

//进入UI线程
--> handleLaunchActivity()
--> performLaunchActivity()
//建立Activity实例
--> Instrumentation.newActivity()
--> Activity.onCreate()
复制代码

解释

  • ActivityThread:App的真正入口。当开启App以后,会调用main()开始运行,开启消息循环队列,这就是传说中的UI线程或者叫主线程。与ActivityManagerServices配合,一块儿完成Activity的管理工做;
  • ApplicationThread:用来实现ActivityManagerService与ActivityThread之间的交互。在ActivityManagerService须要管理相关Application中的Activity的生命周期时,经过ApplicationThread的代理对象与ActivityThread通信;
  • Instrumentation:能够理解为应用进程的管家,每一个应用程序只有一个,每一个Activity内都有该对象的引用,ActivityThread要建立或暂停某个Activity时,都须要经过Instrumentation来进行具体的操做;
  • ActivityStack:Activity在AMS的栈管理,用来记录已经启动的Activity的前后关系,状态信息等。经过ActivityStack决定是否须要启动新的进程;
  • ActivityRecord:ActivityStack的管理对象,每一个Activity在AMS对应一个ActivityRecord,来记录Activity的状态以及其余的管理信息。其实就是服务器端的Activity对象的映像;

Question 1: 如何判断APP是否已经启动? AMS会保存一个ProcessRecord信息,有两部分构成,“uid + process”,每一个应用工程序都有本身的uid,而process就是AndroidManifest.xml中Application的process属性,默认为package名。每次在新建新进程前的时候会先判断这个 ProcessRecord 是否已存在,若是已经存在就不会新建进程了,这就属于应用内打开 Activity 的过程了。

从Activity建立成功到显示画面

onCreate()方法中先执行setContentView()方法将对应的xml文件传入,以后会去调用window.setContentView(),最终会在这里建立Decorview并填充标题栏、状态栏,而后获取contentParent,而后调用LayoutInflater.inflate解析xml文件获取根root(ViewRootImpl),经过root.addView()将contentParent添加到ViewRootImpl中去,至此onCreate()结束。

开始onResume()阶段,在开始会向H类发送一个消息,而后在ActivityThread中获取以前建立的Decorview并调用windowManager.add(),最后在windowManager中将窗口和窗口的参数传到root.setView(),而后ViewRoot经过Binder调用WMS,使WMS所在的SS进程接收到按键事件时,能够回调到该root,同时ViewRoot会向本身的handler发送一条消息,而后进行处理(performTraversals),以后开始绘制过程(在Surface的canvas上绘制)。

先利用MeasureSpec完成onmeasure(),而后在onlayout()中肯定各元素的坐标,ondraw()负责将view画到canvas上,再经过Surface进行跨进程最终调用Native层的SGL、openGI,最后再去调用硬件CPU进行渲染操做,最终界面显示在你眼前

解释

  • DecorView:界面的根View,PhoneWindow的内部类
  • contentParent:全部View的根View,在DecorView里面
  • ViewRootImpl:ViewRoot是GUI管理系统与GUI呈现系统之间的桥梁,WindowManager经过ViewRootImplDecorView起联系。而且,View的绘制流程都是由ViewRootImpl发起的
  • SGL:底层的2D图形渲染引擎

参考文章:

相关文章
相关标签/搜索