apk的打开过程
Table of Contents
APK(Android Package)在打开(即启动应用)的过程中,涉及多个技术细节和系统组件的协作。
1. 用户触发启动
- 用户点击应用图标时,系统会接收到启动应用的请求。
- 这个请求会被传递给Launcher(桌面应用),Launcher 通过
Intent
启动目标应用的主 Activity。
2. 启动 Intent 的传递
- Launcher 会创建一个
Intent
对象,指定要启动的 Activity(通常是应用的主 Activity)。 - 这个
Intent
会被发送给系统的ActivityManagerService(AMS),AMS 负责管理 Activity 的生命周期和任务栈。
3. 进程创建(如果需要)
- 如果应用尚未运行,AMS 会通知Zygote 进程创建一个新的应用进程。
- Zygote是 Android 系统的孵化器进程,预加载了系统核心库和资源。
- Zygote 通过
fork()
系统调用创建新进程,并加载应用的入口类(android.app.ActivityThread
)。
- 新进程启动后,会初始化应用的运行时环境,包括:
- ART/Dalvik 虚拟机:加载应用的 DEX 文件。
- 主线程(UI 线程):创建并启动主线程,用于处理 UI 事件。
4. Activity 的创建和初始化
- 在新进程中,
ActivityThread
会处理 AMS 的请求,创建目标 Activity 实例。 - 具体步骤包括:
- 加载类:通过类加载器加载 Activity 类。
- 创建实例:调用 Activity 的构造函数创建实例。
- 调用生命周期方法:
onCreate()
:初始化 Activity,加载布局和资源。onStart()
:Activity 可见但未获得焦点。onResume()
:Activity 获得焦点,进入运行状态。
5. 加载布局和资源
- 在
onCreate()
方法中,Activity 会通过setContentView()
加载布局文件(XML)。 - 系统会解析布局文件,创建视图树(View Hierarchy),并将其渲染到屏幕上。
- 资源文件(如图片、字符串等)会从 APK 中加载并缓存。
6. 绘制 UI
- 系统会触发视图树的绘制流程:
- 测量(Measure):计算每个视图的大小。
- 布局(Layout):确定每个视图的位置。
- 绘制(Draw):将视图绘制到屏幕上。
- 这个过程由ViewRootImpl和Choreographer协调完成。
7. 事件处理
- 应用启动后,主线程会进入事件循环(Event Loop),等待用户输入(如触摸事件)。
- 事件由InputManagerService捕获,并通过
WindowManagerService
传递给目标 Activity。
8. 后台服务启动(如果有)
- 如果应用声明了后台服务(Service),系统可能会在启动时初始化这些服务。
- 服务的生命周期方法(如
onCreate()
和onStartCommand()
)会被调用。
9. 动态权限请求(如果有)
- 如果应用需要运行时权限(Dangerous Permissions),系统会弹出权限请求对话框。
- 用户授权后,应用才能访问受保护的资源(如摄像头、位置等)。
技术细节
-
关键组件:
- ActivityManagerService (AMS):管理 Activity 的生命周期和任务栈。
- Zygote:孵化应用进程。
- ActivityThread:应用的主线程,负责处理 Activity 的生命周期。
- ViewRootImpl:管理视图树的绘制和事件分发。
- Choreographer:协调 UI 渲染和帧同步。
-
目录和文件:
/data/app/<package_name>
:APK 文件存储位置。/data/data/<package_name>
:应用私有数据目录。/data/dalvik-cache
:优化后的 DEX 文件存储位置(ART 虚拟机)。
通过以上步骤,APK 文件会被成功启动,用户可以与应用进行交互。
明天学习一下在看[[20250126-机器码]]时了解到的一个名词:指令重排