Android简介
Android系统的源代码数量非常庞大,这些代码主要分成4层,从低到高为Linux内核层、系统库层、应用程序框架层和应用程序层,它们分别由驱动工程师、系统工程师、框架工程师和应用程序工程师来开发。如图所示为整个Android系统的框架图:
Linux内核层
Android是基于Linux内核的,Linux内核为Android框架层提供了非常和核心的支持,比如Camera驱动、USB驱动、Wi-Fi驱动等。还实现了比如非常重要的进程间通信Binder驱动。Linux内核层就好比房子的地基一样。
系统库层
系统库层主要包括Android Libraries和Android Runtime。
Android Libraries:主要包括SQLite库、Webkit库和OpenGL库等。SQLite库用来支持数据库,Webkit库支持浏览器,OpenGL库支持3D图像。
Android Runtime:主要包含一个Core库和Android虚拟机。Core库提供了Java编程语言的功能,而Android虚拟机用来运行apk程序的。每一个Android应用程序都在自己的独立进程中运行,都拥有一个独立的虚拟机实例。
应用程序框架层
应用程序框架层,即Android Framework层,主要实现Android系统的核心服务和提供接口来开发应用程序,这些核心服务支撑整个Android系统的上层,分为多个模块:
- ActivityManagerService:管理Android四大组件和进程内存
- WindowManagerService:管理Android窗口
- PackageManagerService:包管理服务,主要是apk的安装和权限的分配
- PowerManagerService:电源服务
- MultMedia:多媒体服务
- NotificationManagerService:通知管理服务
- View系统:UI的绘制和UI事件的分发
- ……..
应用程序层
应用程序层,即Android应用程序,它包括系统应用和第三方应用。大多数Android开发人员都从事应用程序层开发。
开机启动流程
开机到Launcher显示
Android系统的开机过程即Android的启动过程,可以分为两个阶段,第一个阶段是Linux的启动,第二阶段是Android的启动。Linux的启动主要是加载Bootloader和内核启动。这里我们主要了解第二阶段Android的启动:
这个过程从Init进程启动开始,到Launcher主界面显示结束。当Init进程启动之后,它主要做两件核心的事情,一是启动属性服务类实现Android系统设置和获取,二是他会去解析init.rc文件,并且启动配置在这个文件里的native service进程,如Zygote、SurfaceFlinger、Vold等Native进程。当SurfaceFlinger进程被Init进程启动后,它会去启动开机动画程序bootanimation。Init进程在启动SurfaceFlinger进程的同时,也会去启动Zygote进程,当Zygote进程启动好了之后,Zygote进程会去启动SystemServer进程,而SystemServer进程启动了Android框架层的核心服务AMS、WMS、PMS等,这些服务支撑整个上层应用程序。当SystemServer进程中的核心服务AMS启动好了之后,AMS会启动Android应用程序Launcher主界面,Launcher会加载所有的应用程序图标到界面上,当Launcher启动完成之后,AMS会去请求SurfaceFlinger退出开机动画,开机动画一退出,Launcher界面就显示出来了。
系统开机大致图示:
Launcher启动应用程序
Launcher应用程序显示的主界面其实是个Activity,在其原生的AndroidManifest文件里配置了“android.initen.category.HOME”属性,即:
<category android:name="android.intent.category.HOME"/>
Launcherde在onCreate()方法中加载了应用程序图标的操作,即把安装的所有程序以图标的方式显示到主界面桌面上,当在主界面的桌面上点击某个应用程序的图标时,就会启动该应用程序,Launcher会通过PackageManagerService的queryIntentActivities()方法来获得那些Action类型为Intent.ACTION_MAIN,Category类型为Intent。CATEGORY_LAUNCHER的Activity,从而启动对应的Activity作为应用程序的主界面入口。
Android系统开机慢的原因:
- 在启动Launcher的时候PackageManagerService会去解析已经安装的应用程序,安装的应用程序越多,解析时间也就越长。
- 在Android系统的Zygote进程启动过程中,它会去预加载资源和类,消耗时间,这部分将会在后面讲解Zygote进程时详说。
Android Init进程
Init进程在Android系统中非常重要,它是Linux系统中用户空间的第一个进程。由于Android系统基于Linux,所以它也是Android系统用户空间第一个进程。作为常见的天字一号进程,它的进程号为1。Init进程的源代码在system/core/init/目录下,主文件是init.cpp。
开机动画bootanimation
Android系统在启动的过程中,一般有两个开机动画,每一个界面都是用来表示不同的启动阶段。第一个开机界面在内核启动的过程中出现,是静态的界面。第二个开机界面在系统服务启动的过程中出现,是动态的界面。而这个动态的界面就是开机动画bootanimation,由SurfaceFlinger进程启动。当Android系统完全启动之后,Android系统框架里的ActivityManagerService服务会调用WindowManagerService里的接口来请求SurfaceFlinger停止开机动画bootanimation,以便显示Launcher界面。
第一个界面由于是kernel启动的,所以它的实现在kernel里。第二个界面是bootanimation,它是framework里的一个Native Service,即它是一个Native进程。具体的代码实现在framework/base/cmds/bootanimation/目录里。
设计两个开机界面的原因:
第一个开机界面是为了显示长按电源键有效果,系统已经启动。而第二个界面是由于Android系统的启动时间较长,从而显示第二个动态的开机动画,其可能是原生的一帧帧图片播放或是播放视频。
下图为开机动画显示和退出的整体过程框架:
开机动画显示和退出的整体过程总结:
Android系统开机之后,Android内核先启动,接着启动Android用户空间的第一个进程,即启动Init进程。Init进程启动之后去解析init.rc中配置的那些Native进程,其中包括SurfaceFlinger进程和Zygote进程。当SurfaceFlinger进程被Init进程解析并启动后,就会进入main函数,在它的main()函数里调用init函数,而在init()函数会设置系统属性“ctl.start”的值为“bootanim”,这样,程序bootanimation就被启动显示开机动画。在SurfaceFlinger被启动的同时,Zygote进程也会被Init进程启动,Zygote进程会去启动SystemServer进程,而SystemServer进程启动了Android框架层的核心服务AMS、WMS、PMS等。当Android系统核心服务AMS启动完成之后,AMS就会去调用它的startHomeActivityLocked()方法来启动主界面Launcher,当Launcher启动完成之后,AMS就会去通知WMS调用SurfaceFlinger的bootFinish()函数,这个函数里会设置属性“service.bootanimation.exit”的值为字符串1,这样bootanimation就退出播放。bootanimation一旦退出,Launcher就显示出来了。