1:前言
之前两篇我们简单的描述了Android智能手机的生产过程以及一个APK的生成过程,这里我们将对从按下电源键一直到启动Home应用这个过程做一个详细的描述,文章将分为两个章节;该章节描述Android系统结构;

2:Android架构

在Android的架构里提出了HAL的概念,这个HAL其实就是硬件独立的意思,Android系统不依赖于某一个具体的硬件驱动,而是依赖于HAL代码,这是因为为了避免Android源码开源性质从而公开了各厂家的源代码,这样,第三方厂商可以将自己不开源的代码封装在HAL层,仅提供二进制代码;

2.1:Android架构之应用层
内置核心应用,如Home,Setting

2.2:Android Framework层

2.2.1:其主要作用有两个:
1)为应用层提供API,那提供API的jar在哪里?在第三层的ANDROID RunTIME Core Libraries中;它叫android.jar,在这个jar中并不包含那些设置为hide的API
2)为应用层提供组件支持,这也是框架层最重要的作用;如listview,textview等;

2.2.2:Android Framework层中重要模块
1)View System: 提供组件如listview
2)Content Providers: App共享数据的数据库
3)Activity Manager: 管理应用程序生命周期并提供常用的导航回退功能

2.3: Androidy运行环境和系统运行库
系统运行库主要包括各种系统库和第三方库;Android运行环境主要是C++或者C实现的,如DVM;

2.3.1: Androidy运行环境中重要模块
在开发Android App过程中,引入的不同的Android版本,都会引入android.jar;这个jar文件就是存在Android运行环境中;

1)Core Librares是对标准java api进行了裁剪,并加入了Android特有的API,如android.jar
2)Dalvik Virtual Machine:Google并没有采用JVM,而是针对引移动设备在内存,供电,处理速度有限的情况下自己设计的Dalvik虚拟机;在Android5.0中,DVM正式推出历史舞台,取而代之的是ART

2.3.2:Android系统运行库重要模块
1)WebKit: 上层浏览器的实现
2)SurfaceManager:显示系统核心,负责绘图合成

2.3.3: DVM JVM和ART
此时我们接触到三种虚拟机,这里做个简单的介绍
1)JVM
java 虚拟机,基于栈编写,需要去栈中读写数据,所需的指令会更多,读写速度慢
Java类会被编译成一个或多个.class文件,打包成jar文件,而后JVM会通过相应的.class文件和jar文件获取相应的字节码。执行顺序为: .java文件 -> .class文件 -> .jar文件

2)DVM
2.1)Dalvik虚拟机,基于寄存器的,读写速度快;
2.2)Dalvik虚拟机由Zygote进程创建和初始化
Zygote它是一个DVM进程,同时它也用来创建和初始化DVM实例。每当系统需要创建一个应用程序时,Zygote就会fock自身,快速的创建和初始化一个DVM实例,用于应用程序的运行。

什么是fock: 一个进程调用fork()函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。然后把原来的进程的所有值都
复制到新的新进程中,只有少数值与原来的进程的值不同。相当于克隆了一个自己。

这样做的好处就是可以共享framework层的资源,库等
2.3)DVM允许在有限的内存中同时运行多个进程
DVM经过优化,允许在有限的内存中同时运行多个进程。在Android中的每一个应用都运行在一个DVM实例中,每一个DVM实例都运行在一个独立的进程空间。独立的进程可以防止在虚拟机崩溃的时候所有程序都被关闭。

DVM会用dx工具将所有的.class文件转换为一个.dex文件,然后DVM会从该.dex文件读取指令和数据。执行顺序为:
.java文件 –>.class文件-> .dex文件 ;

3)ART(Android Runtime)

ART与DVM的区别
DVM中的应用每次运行时,字节码都需要通过即时编译器(JIT,just in time)转换为机器码,这会使得应用的运行效率降低。而在ART中,系统在安装应用时会进行一次预编译(AOT,ahead of time),将字节码预先编译成机器码并存储在本地,这样应用每次运行时就不需要执行编译了,运行效率也大大提升。
用安装时间换运行时间的代表
后续将开设专门的文章讲解ART

2.4 : Android kernal层
遵循linux标准蒙,并增加了适用于移动设备的进程间通信,低内存killer,电源管理以及日志系统(Logger)等标准

3: Android源码下载
因为google被墙的原因,下载源码推荐通过清华大学源码镜像进行下载

推荐一个下载源码的链接

基本上结合清华大学的教程和推荐的链接就可以完成源码下载;
3.1)每次执行repo sync都会更新android源码,目前最新的是7.1.2
3.2)git branch -a,查看有哪些分支,方便你下载对应分支的源码

下图是我下载的7.1.2的源码结构图,是从vmware中拷贝到windows主机的

在从从vmware中拷贝到windows主机的过程中,你会发现有些文件夹是拷贝不到主机的,这是因为linux中有些系统符号不兼容windows,这里没做过多纠结。

我的虚拟机配置,硬盘务必超过120G,安装软件和下载的源码比较大

4:Android源码编译
4.1)Android源码编译会在out/target/product/generic下生成的三个镜像文件:ramdisk.img,system.img,userdata.img以及它们对应的目录树root,system,data。ramdisk.img是根文件系统,system.img包括了主要的包、库等文件,userdata.img包括了一些用户数据,android加载这3个映像文件后,会把 system和 userdata分别加载到 ramdisk文件系统中的system和 data目录下。
刷机的时候三个镜像文件及其三个目录树就是我们刷机的关键

编译指定模块
4.2)make 模块名
这种方法适合第一次编译,会把依赖的模块一并编译;
如编译电话模块
我们可以根据模块中Android.mk文件查找模块名,LOCAL_PACKAGE_NAME:=Phone
进入到源码跟目录 执行make Phone即可

4.3)mmm命令
在源码根目录编译指定模块,参数为模块的相对路径,只能在第一次编译后使用
如:mmm packgae/apps/phone

4.4) mm命令
用于在模块跟目录编译这个模块,只能在第一次编译后使用
如cd ~/package/apps/phone $ mm

编译Android上层系统源码
a:进入到源码跟目录,执行 . build/ envsetup.sh 导入预设基本

. 是shell命令,作用是从后面的文件中读取指令并执行,注意 . 后面有空格
b : 指定产品名和编译变量 执行 lunch命令
c : 编译全部源码 执行 make -j8(开启8线程开始编译)

更多相关文章

  1. Kotlin For Android简介——有趣实用的功能
  2. iOS 开发者的 Android(安卓)第一课
  3. Android用无线调试真机及在Eclipse的File Explorer中访问真机的D
  4. android Button设置text属性为字母时,字母自动变成大写
  5. android 如何动态的加载类----app插件技术
  6. 如何将Android(安卓)Studio的工程导入到eclipse中
  7. Android(安卓)HIDL HAL 接口定义语言详解
  8. Android(安卓)NDK开发之旅32--云服务器Ubuntu下搭建NDK环境,并编
  9. [转]修改Android的自带程序“屏幕锁”

随机推荐

  1. Android(安卓)ActivityGroup和TabActiviy
  2. Android打开外部DB文件
  3. Android(安卓)Intent的几种用法
  4. android 音量调节时,嘟 的 发声位置
  5. Android开发之修改标题栏样式
  6. Android之SharedPreferences对参数数据的
  7. android警告 —— This Handler class sh
  8. Android(安卓)SDCard操作(文件读写,容量
  9. android 背景图片的设置
  10. day2