0. 前言  

从Android手机打开开关,到我们可以使用其中的app时,这个启动过程到底是怎么样的?

1.  系统上电

当给Android系统上电,在电源接通的瞬间,CPU内的寄存器和各引脚均会被置为初始状态,CPU复位之后,程序指针会指向启动地址,从该地址读取并直接运行启动程序的可执行代码,或者将可执行代码与数据载入CPU内置的RAM中再运行。这一段代码,放在PC中,叫做BIOS,而在Android等嵌入式系统中就叫做Bootloader。

2.  Bootloader引导程序

通过Bootloader引导程序,可以初始化硬件设备,建立内存空间映射图,为操作系统内核准备好环境,完成整个系统的加载启动任务。

 Bootloader是支持交互式操作的,一般刷机中会用到的Fastboot模式,就是在Bootloader启动之后,根据用户输入的指令(在手机上用音量键,Home健等操作),停留在当前状态。

而正常情况下,Bootloader程序执行完成之后,就会开始加载Android操作系统。

3.  加载内核

我们知道Android操作系统的内核其实就是Linux内核。当Bootlader引导程序启动之后,就会进入Linux的内核引导阶段。该阶段会初始化内核和设备驱动,接着启动内核,挂载文件系统,最后启动用户空间进程。

4.  Init程序

Init程序是用户空间的第一个进程。它负责解析一个叫做init.rc的配置文件,启动Android系统底层运行的一些服务进程。

init.rc文件定义了不同的Action和Service,其格式如下:

//Action是以关键字on来定义的,紧接着的boot是一个触发条件
//如下面的action表明当Android启动(boot)的时候,要做些什么事情
// Action boot之后的class_start core等,是Init程序在开机时会启动的服务
//这些服务包括ueventd, servicemanager, void, zygote,installd, ril-daemon等,我们一般称它们为守护进程
on boot
...
class_start core
class_start main //Service是以关键字servie来定义的,紧跟着的是其名字和其启动的文件
//如下会执行/system/bin/serviemanager文件,并将其命名为servicemanager
service servicemanager/system/bin/servicemanager #声明一个service,而servicemanager则是其名字
class core #optioin, 该service属于core类
usersystem $option,该service属于System用户
group System

Init程序同时也会开启属性服务,存放一些关于Android系统的全局系统设置信息。

最后,当所有的Action和Service都启动完成之后,Init程序就会进入一个无限的循环,监听系统中发生的事件,对一些事件进行处理,比如重启某些服务等。

5.  ServiceManager

ServiceManager是Init程序启动的守护进程之一,它是Android中Binder通信机制的基础。

ServiceManager提供了注册,检索服务的功能。在Zygote子进程system_server启动的每一项服务都会将其注册到ServiceManager中,由ServiceManager来统一进行管理。值得注意的是,ServiceManager本身也是一个Service,所以它也会将自己注册到自身上面。

而ServiceManager启动的过程做了三件事:

(1)打开Binder设备,把Binder设备映射到内核空间中,由于内核空间是所有进程共享的区域,所以借助这块区域,可以实现不同进程间资源的共享,从而达到进程间通信。

(2)ServiceManager本身会变成一个ContextManager,即上面所说的注册到自己身上,负责各种Service的上下文管理。

(3)最终ServiceManager也是会进入一个无限循环。

6.  Zygote

Zygote也是由Init程序启动的其中一个服务,是Android中的第一个Dalvik虚拟机。在之后,所有的Dalvik虚拟机都是由Zygote孵化出来的,这是因为Android中每一个应用都有着自己的进程,而每一个进程中都着一个Dalvik虚拟机,如果每起一个应用就创建一个虚拟机,效率太低,而通过复制Zygote,不仅可以提高创建的速度,还能够共享系统和框架的资源,可以大幅度提高应用程序启动的效率。

Zygote启动之后:

(1)首先会创建一个socket,等待某个客户端的请求。

(2)接着创建其第一个子进程system_server。system_server会开启Android系统的Native Service和Java Service。

其中Native Service就是那些利用JNI实现的共享库,而Java Service则是通过Java语言实现的ActivityManagerService等,都是在这个阶段由system_server启动并注册到一个叫ServiceManager的服务进程中。

ActivityManagerService启动之后,会进入到一个叫System Ready的状态,而在其达到System Ready的状态之前呢,就会启动一个叫做Launcher的应用,而这个Launcher就是Android系统启动成功之后见到的Home桌面了。

而在SystemReady的状态,其会跟Zygote启动之初的Socket进行通信,告诉Zygote一切已经就绪。

(3)Zygote知道已经启动成功,就开始进入一个无限的循环,在Socket上等待请求的到来。

至此,从Android手机上电的那一刻起,到加载内核,到最后显示Home桌面的整个过程就结束了。


7.  APK的安装过程

Android系统启动的过程中会启动一个应用程序管理服务PackageManagerService(系统启动的时候由SystemServer组件启动),这个服务负责扫描/system/framework、/system/app、/vendor/app、/data/app、/data/app-private五个目录下的APK文件,然后解析该APK中的AndroidManifest.xml以获得应用程序相关信息,其中最重要的就是依据sharedUserId这个配置来让系统确定每个APK运行在哪个进程。
继而为这个APK分配Linux用户ID、用户组ID以便APK在系统中可以获取到合适的运行权限、资源访问权限。
最后将之前获得的权限和APK安装信息保存到本地的一个配置文件中,以便下次在安装这些APK时可以将需要的APK信息很快速的恢复回来。

8.  应用启动流程

8.1  应用的冷热启动

Android中的冷启动指当启动应用时,后台没有该应用的进程,这时系统会重新创建一个新的进程分配给该应用所以会先创建和初始化Application类,再创建和初始化MainActivity类(包括一系列的测量、布局、绘制),最后显示在界面上。

Android中的热启动指当启动应用时,后台已有该应用的进程(如按back键、home键,应用虽然会退出,但是该应用的进程是依然会保留在后台,可进入任务列表查看),热启动就不会走Application这步了。

 

8.2  应用的启动流程

当点击app图标时,系统会从Zygote进程中fork创建出一个新的进程分配给该应用,之后会依次创建和初始化Application类、创建MainActivity类、加载主题样式Theme给MainActivity以及配置Activity层级上的一些属性、再inflate布局、当onCreate/onStart/onResume方法都走完了后最后才进行contentView的measure/layout/draw显示在界面上,所以直到这里,应用的第一次启动才算完成,这时候我们看到的界面也就是所说的第一帧。

总结一下,应用的启动流程如下:

Application的构造器方法——>attachBaseContext()——>onCreate()——>Activity的构造方法——>onCreate()——>配置主题中背景等属性——>onStart()——>onResume()——>测量布局绘制显示在界面上


8.3  启动时间优化

可以通过adb shell命令的方式进行测量应用的启动时间:

adb shell am start -W [packageName]/[packageName.MainActivity]

应用初始化的时候采取以下策略可减少启动时间:

(1)在Application的构造器方法、attachBaseContext()、onCreate()方法中不要进行耗时操作的初始化。

(2)对于MainActivity,由于在获取到第一帧前,需要对contentView进行测量布局绘制操作,尽量减少布局的层次,考虑StubView的延迟加载策略,当然在onCreate、onStart、onResume方法中也要避免做耗时操作。


感谢:

http://blog.csdn.net/linmiansheng/article/details/37728903

http://blog.csdn.net/u010687392/article/details/50518343

http://www.2cto.com/kf/201607/528367.html

http://www.jianshu.com/p/0b0d6f684580

Android开发——Android系统启动以及APK安装、启动过程的更多相关文章

  1. Android开发-Android Studio问题以及解决记录

    [Android开发] Android Studio问题以及解决记录   http://blog.csdn.net/niubitianping/article/details/51400721 1.真 ...

  2. Android开发——Android M(6.0) 权限解决方案

    Android开发--Android M(6.0) 权限解决方案 自从Android M(6.0)发布以来,权限管理相比以前有了很大的改变,很多程序员发现之前运行的好好的Android应用在Andro ...

  3. Android开发——Android多进程以及使用场景介绍

    个层级,具体可以查看Android开发--Android进程保活招式大全中1.1部分的内容,这里就不赘述了. 根据进程中当前活动组件的重要程度,Android 会将进程评定为它可能达到的最高级别.例如 ...

  4. Android开发-Android Studio安装

    开发平台:Windows 7 旗舰版,SP1 开发工具:Android Studio1.2正式版 1.打开http://www.androiddevtools.cn/ ,找到Android Studi ...

  5. Android开发入门——Andoird Studio的安装与配置

    Android的开发离不开Java,仍然需要对Java进行安装与配置,所以我写了上一篇文章,Java的安装与配置. 开始进行Android Studio的安装与配置. 一.进行配置Java,如果电脑里 ...

  6. android开发——Android开发中的47个小知识

    1.判断sd卡是否存在  boolean sdCardExist = Environment.getExternalStorageState().equals(android.os.Environme ...

  7. Android开发 Android Studio2.0 教程从入门到精通Windows版 - 入门篇

    第一篇 介绍了Android Studio开发环境以及Genymotion虚拟机安装方法,本节将给大家介绍如何使用Android Studio开发应用. 开发第一应用 可以开发属于自己的应用,是否有点 ...

  8. Qt for Android开发Android应用时的各种错误汇总(此片博文不成熟,请大家略过)

    “Qt for Android真的很脆弱,项目能跑起来靠的是奇迹,跑不起来,各种报错才是正常...” 问题一:Qt for Android编译不过:make (e=2): 系统找不到指定的文件. 之前 ...

  9. Android应用程序组件Content Provider的启动过程源代码分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6963418 通过前面的学习,我们知道在Andr ...

随机推荐

  1. February 24 2017 Week 8 Friday

    If you fail, don't forget to learn your lesson. 如果你失败了,千万别忘了汲取教训. Frankly speaking, it is easy to ta ...

  2. 长大DeepMind第一次团队作业

    1.队名 长大DeepMind 2.队员风采 学号 姓名 擅长的技术 编程的兴趣点 希望承担的角色 一句话宣言 B20150304508 晏司举 JAVA,ssm框架,MySQL数据库 JAVA后台服 ...

  3. npm proxy设置网络代理 并使用taobao registry

    npm config set https-proxy http://server:portnpm config set proxy http://server:port npm set registr ...

  4. URI和URL有什么区别

    URI 是从虚拟根路径开始的URL是整个链接如URL http://zhidao.baidu.com/question/68016373.html URI 是/question/68016373.ht ...

  5. Android(java)学习笔记44:Map集合的遍历之键值对对象找键和值

    1. Map集合的遍历之 键值对对象找 键和值: package cn.itcast_01; import java.util.HashMap; import java.util.Map; impor ...

  6. 新手理解HTML、CSS、javascript之间的关系-修订

    几年前写过一篇博文 <新手理解HTML.CSS.javascript之间的关系>,没想到网上出现了不少转载,当时没有太用心,里面的很多内容有待商榷,这里发布重新发布一篇. 网页主要有三部分 ...

  7. c++字符串初始化

    #include<string> string s1 = "abcdefg"; string s2("abcdefg");

  8. ProjectServer如何创建时间表

    默认配置的ProjectServer是没有时间表的,任务汇报的时候不能汇报工时,只能汇报任务的百分比. 但如果有企业一定要用工时来汇报的话,我们就需要开启时间表. 点击服务器设置-->时间报告阶 ...

  9. Swift_Set详解

    Swift_Set详解 点击查看源码 初始化 //初始化 fileprivate func testInit() { //空Set var set = Set<String>() prin ...

  10. 2、开发环境搭建-window平台

    一.搭建ReactNative环境 首先安装node.js和python2.xx版本,不要装python3.xx,这个官方是特别说明的,请注意.NodeJs官方下载:https://nodejs.or ...