众所周知,Android是一个基于Linux实现的操作系统。但对于Linux内核来说,Android也仅仅只是一个运行在内核之上的应用程序,与其他运行在内核之上的应用程序没有任何区别。所以Android也需要运行环境,需要Linux内核在启动完成后加载Android Framework运行所需要的资源。当Framework完成初始化后才能继续启动相应的APK应用程序。

Framework启动分析


Framework运行的第一个Java虚拟机进程为zygote(对应具体程序为app_process,该程序位于system/bin目录下),zygote是APK应用程序的父进程,此后所有的虚拟机进程都由zygote创建。

zygote有两个功能:
1.接受请求创建新的Dalvik进程
2.共享类和资源(需要加载的资源在preload-classes文本文件中声明)

Dalvik虚拟机进程间的关系

对于Android来说,每一个应用程序对应着一个Linux 进程,每一个进程都是一个Dalvik虚拟机,Dalvik虚拟机是一种类似Java虚拟机的实现。

zygote进程在启动时会预先装载共享类和共享资源,这些类及资源实际上就是SDK中定义的大部分类和资源。当zygote进程创建新进程时,新的APK进程只需装载自身类和资源即可。共享的资源位于同一段物理内存空间中,zygote进程及其创建的Dalvik进程都可以访问,这就解决了多个APK共享Framework资源的问题。(更多关于资源的讨论请看Android资源加载机制详解)

zygote创建的第一个进程名为SystemServer,SystemServer创建了一个Socket客户端,并创建了ActivityManagerService线程来管理该客户端。之后所有的Dalvik进程都是由该客户端启动的。当需要启动新的APK进程时,AmS会通过该Socket客户端向zygote进程的Socket服务端发送一个启动命令,然后zygote就会创建(使用fork()创建新进程)出新的应用程序进程。

系统服务
SystemServer进程内部运行着APK应用中能够直接交互的大部分系统服务。比如WindowManagerService(简称WmS),ActivityManagerService(简称AmS),PackageManagerService(简称PmS)等。这些系统服务都是以一个线程的方式生存在SystemServer进程中。SystemServer启动的各种服务线程如下所示:

  • PowerManagerService电源管理服务
  • ActivityManagerService管理Activity
  • PackageManagerService程序包管理服务
  • BatteryService电池管理服务
  • LightService自然光强度感应传感器服务
  • VibratorService震动传感器服务
  • ClipboardService剪切板服务
  • NetworkManagerService网络管理服务
  • InputMethodManagerService输入法管理服务
  • BluetoothService蓝牙服务
  • ...

Dalvik与Android Runtime(ART)
Dalvik是一种类Java虚拟机的实现,其执行的是class优化后的dex字节码文件。Dalvik通过一个JIT(Just-In-Time)编译器去解释字节码,但执行效率并不理想。

自动Android 4.4后安卓就内置了ART实现,从5.0开始更是直接抛弃了Dalvik全面使用ART。ART通过AOT机制(Ahead-Of-Time)在应程序安装时将字节码编译成机器语言,因此执行速度更快。并且ART也完全兼容Dalvik。

应用程序启动分析


在计算机的世界里每个程序都有一个main()方法,程序代码都是从main()方法开始执行,Android应用程序也不例外。

当应用程序启动时系统首先会为其创建一个Dalvik虚拟机进程,并加载APK应用程序类及资源。然后,APK应用程序从ActivityThred的main()方法处开始执行。

首先main()方法为UI线程创建一个消息队列(MessageQueue)。然后创建ActivityThread对象,ActivityThread初始化时会创建一个Handler和一个Binder。Binder负责接收远程AmS的IPC调用,接收到调用后通过Handler将消息发送到消息队列,UI主线程会异步地从消息队列中取出消息并执行相应操作,比如start,stop,pause等。

接着UI主线程调用Looper.loop()方法进入消息循环体,进入后就会不断从消息队列中读取并处理消息。

ActivityThread是APK程序的UI线程,也就是我们所说的主线程。主线程要求执行时间不能超过5秒,超过就会报ANR,这个5秒就是UI线程消息队列循环一次的最大时间阈值。

当ActivityThread接收到AmS发送的start某个Activity消息后,就会创建指定Activity对象。Activity又会创建PhoneWindow类,PhoneWindow创建DecorView,DecorView内部包含Activity.setContentView(R.layout.xxx)指定的布局。

创建完成后,Activity需要将布局显示在屏幕上,于是调用WindowManager.addView()方法。WindowManager为Activity对应的窗口(Window)创建一个ViewRoot对象(每一个窗口对应一个ViewRoot对象),然后调用WmS提供的远程接口将窗口(布局)显示到屏幕上。至此应用程序中的Activity就显示在屏幕上了。

APK中的线程
在现在操作系统中,任何应用程序都运行在线程之中。客户端在启动时系统会首先为其分配一个线程,然后该线程从程序的入口处开始执行。对于包含Activity的客户端程序,至少包含三个线程:

  1. 主线程,又称UI线程,也就是应用程序本身所在的线程,主要用于处理用户消息以及绘制程序界面。
  2. ViewRoot.W对象对应的线程,Activity启动后会创建一个ViewRoot.W对象,W对象继承自Binder,因此会启动一个对象负责接收Linux Binder驱动的IPC调用。
  3. ApplicationThread对象所对应的线程,该对象也继承自Binder,因此也会启动一个线程用于IPC调用。

自定义Thread与UI线程的区别
对于UI线程,在启动时已经创建了消息队列(MessageQueue),既在ActivityThread的main()方法中已经使用Looper.prepareMainLooper()方法为UI线程添加了Looper对象。程序员可以直接在Activity中定义Handler对象发送处理消息。

而对于普通线程,需要手动调用Looper.prepareLooper()方法为Thread创建消息队列,这样才能定义Handler处理消息。即不能直接在Thread中定义Handler。

从使用场景上说,就是不能直接给Thread对象发消息,但是却可以给UI线程发消息。

具体Handler的使用及解释请移步Android异步通信机制详解

一些重要的类:


下面是一些系统中常见的类及其功能介绍,通读一遍会对理解Android源码很有帮助。

两个重要的系统服务

  • WindowManagerService,管理所有的窗口,包括创建删除窗口,隐藏显示窗口,决定窗口的层级顺序,指定当前正在与应用程序交互的窗口。
  • ActivityManagerService,内存管理,进程管理,统一调度所有应用程序中的Activity。所有Activity的启动必须通知AmS,AmS也决定了某个进程会不会被杀死。

两个消息处理类

  • KeyQ类:该类是WmS的内部类,继承自KeyInputQueue,一旦创建就立即启动一个线程,该线程会不断读取用户UI操作消息,比如按键、触摸屏、等,并把这些消息放到一个消息队列QueueEvent类中。
  • InputDispatcherThread类:该类一旦创建也会启动一个线程,该线程会不断地从QueueEvent中读取用户消息,并进行一定的过滤,过滤后发送给当前活动的而应用程序中。

其他常用类

  • ActivityThread类,应用程序主线程类,所有的APK都有且仅有一个ActivityThread类,程序的入口为该类中的static main()方法,ActivityThread所在的线程即为UI线程或主线程。
  • ViewRoot类,WmS管理客户端窗口时,需要通知客户端进行某种操作,这些都是通过IPC调用来完成的,而客户端在接收到IPC后,都需要将该调用转换成本地异步调用。ViewRoot继承自Handler,其作用就是将远程接口调用转换成本地异步调用。
  • W类,ViewRoot内部类,继承自Binder,Wms通知客户端时就是该类进行IPC调用。该类内部会向其所在的ViewRoot发送一个Handler消息,以便进行异步处理。
  • Window类,是一个抽象类,提供了一套操作窗口的通用方法(Callback接口)。Activity就是通过实现这个Callback接口来获得对消息的处理机会。因为消息首先会由WmS传递给窗口中的View树,View树不处理消息的话才会传递给Window,这时候就会回调Activity实现的Callback方法使Activity有机会处理事件。
  • PhoneWindow类,是Window的具体实现类,其内部保存有DecorView对象。
  • DecorView类,应用程序视图的根布局View,该类继承自FrameLayout。客户端使用WindowManager添加窗口就是将该类(及其子View)添加到WmS中,并将其所代表的视图绘制到屏幕上。
  • Activity类,该类APK程序最小运行单元。ActivityThread根据用户的操作选择加载哪个Activity。
  • WindowManager类,该类是WindowManagerService在客户端的管理类,客户端通过WindowManager申请创建一个窗口,而具体创建窗口的任务是由WMS来完成的。

参考资料
ART无缝替换Dalvik虚拟机

更多相关文章

  1. android绑定远程服务以及android接口定义语言(aidl)
  2. Android(安卓)5 消息机制源码分析
  3. Android仿人人客户端(v5.7.1)——网络模块处理的架构
  4. 转: Android异步加载图像小结
  5. android Message的简单实例
  6. Android(安卓)获取进程名称(可以区分内部进程)
  7. 【绝对干货】超全Android中高级面试复习大纲,覆盖所有面试知识!(上
  8. Android(安卓)异步加载解决方案
  9. Android(安卓)通过handler和message在子线程里面去更新UI

随机推荐

  1. Android(安卓)推送通知指南
  2. Android命令monkey测试
  3. android 命令行安装apk
  4. Android测量View宽和高的一般通用方法
  5. Android项目结构
  6. Android入门2—创建AVD
  7. Android(安卓)Java调用ffmpeg命令
  8. android的消息机制
  9. android开发视频资源 电驴10G下载
  10. Android自适应屏幕大小和layout布局