专栏名称: 郭霖
Android技术分享平台,每天都有优质技术文章推送。你还可以向公众号投稿,将自己总结的技术心得分享给大家。
目录
相关文章推荐
stormzhang  ·  又被平均了? ·  21 小时前  
鸿洋  ·  安卓应用跳转回流的统一和复用 ·  3 天前  
郭霖  ·  使用Hilt来协助封装网络请求 ·  1 周前  
郭霖  ·  Android 跨进程+解耦的数据持久化方案 ·  1 周前  
鸿洋  ·  一个大型 Android 项目的模块划分哲学 ·  1 周前  
51好读  ›  专栏  ›  郭霖

Android系统启动源码分析

郭霖  · 公众号  · android  · 2017-05-19 08:00

正文

今日科技快讯

昨日谷歌I/O2017开发者大会于凌晨1:00在加州山景城召开,主要包含了以下内容:

  • Google Assistant(谷歌助手):目前正在与亚马逊Alexa、苹果Siri和微软小娜竞争声控智能助理市场。

  • 新推出Google Lens,用户可在相机界面直接识别文字和其他信息。

  • Beta版Android O即日起对普通用户开放。Android O包含众多新功能,比如自动填充、重新设计的“系统设置”以及可选下载的字体、支持Kotlin语言开发等等。

  • 谷歌携手高通、联想和HTC开发独立VR头设,预计今年晚些时候推出。

  • 谷歌展示了正在开发的VPS(视觉定位服务),使用计算机视觉绘制真实世界内的图像,将3D导航提升到新高度。

作者简介

明天就是周末啦,提前祝大家周末愉快!

本篇来自 罗享 的投稿,带领大家阅读Android系统启源码,希望对大家有所帮助!

罗享 的博客地址:

http://blog.csdn.net/ynztlxdeai

正文

解读Android的源码可以让我们更好的学习系统的优秀源码,以及google工程师对于一个程序的是如何实现的,从源码的分析也可以强化我们的编程思想。

Android系统启动流程源码分析,基于Android5.1(个人比较喜欢这个版本的源码,因为改动比较大)

Android系统是基于Linux内核的,所以在Android启动的时候会先去加载linux内核,内核启动的时候会去加载各种驱动以及数据结构等,Android的第一个进程是初始化进程(init).

进程是由C代码实现的,即 init.c;所以我们先从 init.c 开始阅读.由于 init.c 文件在Android源码中是有很多个的,我们需要阅读的是内核 core 的 init文件,注意包名不要错误.

1. init.c的main函数

在C语言中,main方法 是函数的入口,我们先从 main函数 开始;由于是分析代码,所以我会把不需要的部分的代码删除,仅留下部分作为例子:

2. init.rc解读

init.rc 是 linux系统 下的一个启动配置文件,在android中的主要工作如下:

setp1:文件系统的初始化和写入,变更权限等

setp2 服务的启动,如下实例是一个大家比较熟悉的服务,网络模块服务启动,此项初始化了socket的网络通信:

setp3 重点服务讲解,孵化器服务

服务器服务 zygote,进程的出现都是有孵化器完成的,也就是说孵化器进程是母进程

但是比较奇怪的是并没有在这个文件中出现直接启动的服务器进程的服务呢?这个就比较麻烦啦,哈哈

好好想一下,文件中既然有提到,onrestart restart zygote,从Java的思想出发的话,这个文件里面一定是导入了服务器进程的包的,那么我们看一下文件的关联文件有哪些吧

在文件的顶头会发现有一个import /init.${ro.zygote}.rc的文件关联,那么去找一下这个文件吧,搜索这个文件会发现有好几个,因为操作系统的位数分为了四个,但是其中内容都是一样的,细微差距就是 app_process 的路径文件夹名字会不一样,不过都指向同一个路径 

如下:

setp4 在这个服务中,可以看到路径是在 app_process,看一下这个路径中的文件,只有一个文件 App_main.cpp,这个C++文件就是孵化器进程了.这次是一个C++文件,C++和C语言一样,入口函数都是main函数

3. 孵化器App_main.cpp解读

4. java孵化器类ZygoteInit.java解读

step1 package com.android.internal.os;此类所在包

step2 对于java代码而言就没有什么main函数了,我们要从构造方法开始看

/**
* Class not instantiable.
* 比较尴尬 不给调用
*/
private ZygoteInit() {}

孵化器的类是一个私有的构造方法,是不允许我们直接实例的类,那么按照常规的java代码套路的话,一般是有一个静态方法去创建他或者直接获得一个实例的,但是找了一下,居然没有,哈哈!但很是意外的发现有一个main方法:

step3 main方法解读

5. 预加载preload()

step1 方法内容

step2 preloadClasses()预加载类说明

step3 preloadResources() 加载资源,这个方法比较简单没什么好说的

step4 preloadOpenGL()方法,加载 opengl 相关,opengl 是一个开源组织维护的,加载的话确实就是和java依赖库一样简单,没什么好解释的

step5 preloadSharedLibraries() 加载依赖库

step6 WebViewFactory.prepareWebViewInZygote() 浏览器作为APP中一个比较特殊的应用.这里就不详解

6. 启动Android系统服务介绍

step1 方法声明

7. SystemServer分析

step1 类声明和构造说明

在 Android2.3 的源码中,SystemServer类 还包含了两个内部类,但是在5.1的版本中已经把两个内部类合并了(SensorService.cpp中),有兴趣的可以追溯一下2.3的源码

step2 main方法分析

step3 run方法分析

8. android_servers库源码

step1 源代码查找

step2 nativeInit方法

该方法主要调用了 SensorService::instantiate(),实例了 SensorService对象

step3 SensorService阅读

路径如下 F:\Android5\android5.1\frameworks\native\services\sensorservice
因为 SensorService 启动后执行的就是 onFirstRef方法,所以我们直接看这个方法

9. 后续启动

step1 硬件完成后

startBootstrapServices();
startCoreServices();
startOtherServices();

step2 startBootstrapServices()

step3 startCoreServices(); 

这一段google工程师注释很详细了就不多解释了:

step4 startOtherServices(); 此处代码量非常大,认真慢慢来

10. ActivityManagerService.java

路径依然还是frameworks下

step1 systemReady()方法

总结

对于Android的启动源码呢,涉及到了很多的东西,方方面面,我可能讲的不是很到位,还是各位慢慢吸收理解.多多支持.

更多

每天学习累了,看些搞笑的段子放松一下吧。关注最具娱乐精神的公众号,每天都有好心情。

如果你有好的技术文章想和大家分享,欢迎向我的公众号投稿,投稿具体细节请在公众号主页点击“投稿”菜单查看。

欢迎长按下图 -> 识别图中二维码或者扫一扫关注我的公众号: