zoukankan      html  css  js  c++  java
  • Android底层有一定的认识,研究过相关的Android源码

    一、系统架构:

    一)、系统分层:(由下向上)【如图】

    1、安卓系统分为四层,分别是Linux内核层、Libraries层、FrameWork层,以及Applications层;

    其中Linux内核层包含了Linux内核和各种驱动;

    Libraries层包含各种类库(动态库(也叫共享库)、android运行时库、Dalvik虚拟机),编程语言主要为C或C++

    FrameWork层大部分使用java语言编写,是android平台上Java世界的基石

    Applications层是应用层,我们在这一层进行开发,使用java语音编写

    2、Dalvik VM和传统JVM的区别:

    传统的JVM:编写.java文件 à 编译为.class文件 à 打包成.jar文件

    Dalvik VM:  编写.java文件 à 编译为.class文件 à 打包成.dex文件 à 打包成.apk文件(通过dx工具)

           将所有的类整合到一个文件中,提高了效率。更适合在手机上运行

    1、Linux内核层[LINUX KERNEL]:

    包含Linux内核和驱动模块(比如USB、Camera、蓝牙等)。

    Android2.2(代号Froyo)基于Linux内核2.6版本。

    2、Libraries层[LIBRARIES]:

    这一层提供动态库(也叫共享库)、android运行时库、Dalvik虚拟机等。

    编程语言主要为C或C++,所以可以简单的看成Native层。

    3、FrameWork层[APPLICATION FRAMEWORK]:

    这一层大部分用java语言编写,它是android平台上Java世界的基石。

    4、Applications层[APPLICATION]:应用层

    如图所示:

    系统分层的图整体简化为下面的一张图,对应如下:

    FrameWork层       --------à        Java世界

    Libraries层           --------à        Native世界

    Linux内核层         --------à        Linux OS

    Java世界和Native世界间的通信是通过JNI层

    JNI层和Native世界都可以直接调用系统底层

    二)、系统编译:

    1、主要步骤:系统环境的准备,下载源码、编译源码、输出结果:

    目前系统的编译环境只支持Ubuntu 以及 Mac OS 两种操作系统,磁盘的控件要足够大

    在下载源码的时候,由于Android源码使用Git进行管理,需要下载一些工具,如apt-get install git-core curl

    源码下载好后,进行编译:首先搭建环境,部署JDK(不同的源码编译时需要的JDK版本不同,如2.2需要JDK5,2.3需要1.6),

                                              然后设置编译环境:使用. build/envsetup.sh脚本;选择编译目标(可以根据自己需要的版本进行不同的搭配)

                                              最后通过make –j4的命令进行编译。(make是编译的函数即命令,j4指的是cpu处理器的核数:单核的是j4 x i;双核的是j8)

    最后将编译好的结果进行输出:所有的编译产物都位于 /out 目录下

    2、编译流程图

    二、系统的启动:

    通过Linux内核将Linux系统中用户空间的第一个进程init启动起来,这是安卓世界第一个被启动的进程;

    然后在init中会加载init.rc的配置文件,并开启系统的守护进程(守护media(多媒体的装载)和孵化器zygote(Java世界的开启)),其实此时调试桥的守护进程也被开启起来了;

    然后会处理一些动作执行,在app_main.cpp中会将Zygote孵化器(Zygote是整个java世界的基础,整个安卓世界中(包括framework和app等apk)都是由孵化器启动的)启动起来:

    在app_main中,会调用AppRuntime的start方法开启AppRuntime,其实开启的是其父类AndroidRuntime的start方法被调用,zygote由此就被调用了,此时Native层的右上角有一块区域即ANDROID RUNTIME就启动起来了;

    与此同时,AppRuntime会调用ZygoteInit的main方法启动ZygoteInit(整个的APPLICATION 和FRAMEWORK都会由ZygoteInit带起来的,JNI也被启动起来):

    在ZygoteInit中会调用SystemServer这个类,在SystemServer的main方法中启动init1()方法,将system_init.cpp开启起来,在init1()方法中,将整个Native世界(即LIBRARIES层)开启起来了

    然后在system_init.cpp会调用SystemServer的init2()方法开启ServerThread,通过ServerThread将framework层开启起来(所有的就全部开启起来了),即java世界(APPLICATION FRAMEWORK)就被启动了;此时ActivityManager,WindowManager,PackageManager(最主要,所有的清单文件及apk都有它管理)等等framework层全部开启起来

    一)安卓系统的总体启动顺序:

    1、通过LINUX内核,将init进程启动起来(是Linux系统中用户空间的第一个进程)

    2、将ANDROID RUNTIME这一块的内容启动完毕

    3、分为两步分别启动LIBRARIES(即Native世界)和APPLICATION FRAMEWORK(即java世界)

    1)先启动LIBRARIES(即Native世界)

    2)后启动APPLICATION FRAMEWORK(即java世界)【ActivityManager,WindowManager,电源管理等等】

    二)具体启动流程

    一)、启动流程:

    1、init进程:——安卓世界第一个被启动的进程

           加载一堆配置文件,核心加载的init.rc配置文件,其中包含了孵化器和守护进程都被开启了

    1)、启动服务:开启ServerManager

    守护进程启动(Daemon Process):/system/bin/servicemanager

    守护的是:

    ①、Java世界的开启:onrestart  restart  zygote

    ②、多媒体的装载:onrestart  restart  media

    @、adbd的守护也被开启起来了,即调试桥的守护进程也被开启起来了

    2)、启动孵化器Zygote

           在app_main中启动孵化器Zygote,整个安卓世界中(包括framework和app等apk)都是由孵化器启动的

           【此时虚拟机还没开启起来,只是配置了一些vm的参数】

    3、app_main:——开启孵化器

           app_main中,调用AppRuntime的start方法,将Native层的右上角有一块区域,即ANDROID RUNTIME启动起来

    其中的start方法实际是其父类AndroidRuntime的start方法

    【此时VM虚拟机被开启起来了,通过start方法开启,在AndroidRuntime中并设置了默认的内存大小16M】

    【注册JNI,并启动孵化器Zygote】

    4、ZygoteInit开启

           AppRuntime被启动后,会调用ZygoteInit的main方法,启动ZygoteInit;

           然后,整个的APPLICATION 和FRAMEWORK都会由ZygoteInit带起来的

    5、SystemServer启动:

           ZygoteInit调用SystemServer这个类,在SystemServer的main方法中启动init1()方法,将system_init.cpp开启起来

           在init1()方法中,将整个Native世界开启起来了

    6、ServerThread启动(开启framework层)

    调用SystemServer的init2()方法开启ServerThread,通过ServerThread将framework层开启起来(所有的就全部开启起来了)

           此时ActivityManager,WindowManager,PackageManager(最主要,所有的清单文件及apk都有它管理)等等framework层全部开启起来

     

    二)、具体介绍:

    1、启动入口:init进程

    @、源码位置:/system/core/init/init.c

    @、进程入口:main方法

    1)创建文件夹,挂载设备【通过mkdir的命令创建,挂载一些系统设备后】

    2)重定向输入输出,如错误信息输出【设置了一些输入输出的处理】

    3)设置日志输出【一些系统的日志】

    4)init.rc系统启动的配置文件【加载了相关的信息,不同版本的手机所特有的配置信息】

    ①、文件位置:/system/core/rootdir

    ②、守护进程启动(Daemon Process):/system/bin/servicemanager

    守护的是

    Java世界的开启:onrestart  restart  zygote

           多媒体的装载:onrestart  restart  media

           adbd守护也被开启起来了,即调试桥(adb[Android Debug Bridge])的守护进程(adbd[Android Debug Bridge Daemon])也被开启起来了

    ③、启动Zygote——app_main.cpp【Zygote是整个java世界的基础】

                  当编译之后,在system/bin/app_process下会有孵化器的启动Xzygote

                  守护进程被开启之后,紧接着Zygote也被启动起来了

    5)解析和当前设备相关的配置信息(/init.%s.rc)

    Tips:

    当解析完init.rc和设备配置信息后会获取到一系列Action

    Init将动作的执行划分为四个阶段(优先级由大到小):

    early-init        :初期

    Init                :初始化阶段

    early-boot       :系统启动的初期

    boot               :系统启动

    6)处理动作执行:这个阶段Zygote将被启动

    7)无限循环阶段,等待一些事情发生

    2、Zygote简介:

    @、Zygote启动:app_main.cpp

    1)Zygote简介:

    ①、本身为Native的应用程序

    ②、由init进程通过init.rc加载

    2)功能分析:

    ①、Main方法中AppRuntime.start(),工作由父类AndroidRuntime来完成

    ②、在AndroidRuntime中开启了如下内容

    @startVM——开启虚拟机(查看堆内存设置):默认16M【】

    @注册JNI函数【此时还在Native层,需要将连接java和c的桥(即JNI)搭建好】

    @启动“com.android.internal.os.ZygoteInit”的main方法

    【系统级别的包(由runtime的start方法开启的这个包)】

    start方法实际是其父类AndroidRuntime的

    @进入java世界的入口

    3、ServiceThread的简介:(java世界所做的事情)

    1)preloadClasses();:预加载class

           读取一个preloaded-classes的配置文件

           此文件的内容非常多,这就是安卓系统启动慢的原因之一

           此时会有一个垃圾回收的操作gc(),将无用的回收掉

    2)ZygoteInit在main方法中利用JNI开启com.android.server.SystemServer

    3)启动system_init.cpp处理Native层的服务

    4)然后调用SystemServer的init2()

    5)启动ServiceThread,启动android服务

    6)Launcher启动

    三、开机时的时间消耗:

    1、ZygoteInit.main()中会预加载类

    目录:framework/base/preload-class

    ZygoteInit.main()会加载很多的类,将近1800多个(安卓2.3的)

    2、开机时会对系统所有的apk进行扫描

           需要将所有的应用展现给用户,就需要对apk进行扫描,扫描所有的包

           data目录下有个apk的包

           system目录下有个apk的包

           framework目录下也有相关的包

    3、SystemServer创建的那些Service

  • 相关阅读:
    动态代理:JDK动态代理和CGLIB代理的区别
    关于国密算法 SM1,SM2,SM3,SM4 的笔记
    加密算法比较3DES AES RSA ECC MD5 SHA1等
    通过mybatis向数据库中插入日期数据
    mapreduce流程中的几个关键点
    MapReduce二次排序
    Hadoop自定义分组Group
    编译hadoop2.6.0
    ERROR [org.apache.hadoop.security.UserGroupInformation]
    Java集合分组
  • 原文地址:https://www.cnblogs.com/dubo-/p/6676249.html
Copyright © 2011-2022 走看看