共计 4608 个字符,预计需要花费 12 分钟才能阅读完成。
家喻户晓,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 文本文件中申明)
对于 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 的客户端程序,至多蕴含三个线程:
- 主线程,又称 UI 线程,也就是应用程序自身所在的线程,次要用于解决用户音讯以及绘制程序界面。
- ViewRoot.W 对象对应的线程,Activity 启动后会创立一个 ViewRoot.W 对象,W 对象继承自 Binder,因而会启动一个对象负责接管 Linux Binder 驱动的 IPC 调用。
- 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 来实现的。
文章转自 https://www.jianshu.com/p/37e… 如有侵权,请分割删除。
相干视频:
【2021 最新版】Android studio 装置教程 +Android(安卓)零基础教程视频(适宜 Android 0 根底,Android 初学入门)_哔哩哔哩_bilibili
Android 网络架构搭建与原理解析(一)——通过一个网络申请一步一步见证网络模块的成长_哔哩哔哩_bilibili
【Android 进阶教程】——Framework 面试必问的 Handler 源码解析_哔哩哔哩_bilibili
【Android 进阶课程】——colin Compose 的绘制原理解说(一)_哔哩哔哩_bilibili
【Android 进阶教程】——热修复原理解析_哔哩哔哩_bilibili
【Android 进阶教程】——如何解决 OOM 问题与 LeakCanary 原理解析_哔哩哔哩_bilibili