type
status
date
slug
summary
tags
category
icon
password
本文为学习apk加固的前置知识,here we go!
app两种启动方式
- 冷启动:当启动应用时,后台没有该应用的进程,这时系统会重新创建一个新的进程分配给该应用,然后再根据启动的参数,启动对应的进程组件,这个启动方式就是冷启动。
- 热启动:当启动应用时,后台已有该应用的进程(例:按back键、home键,应用虽然会退出,但是该应用的进程是依然会保留在后台,可进入任务列表查看),所以在已有进程的情况下,这种启动会从已有的进程中来启动对应的进程组件,这个方式叫热启动。
而我们讨论的app启动流程,是针对冷启动的
冷启动流程(app启动流程)

图转文字
- 用户点击应用图标
①点击桌面App图标,Launcher进程采用Binder IPC向system_server进程发起
startActivity
请求- System Server进程处理请求
- ActivityManagerService (AMS) 负责解析Intent、验证权限、创建目标应用进程。
- PackageManagerService (PMS) 提供应用包信息(如
AndroidManifest.xml
)。
- Zygote进程孵化应用进程
- 新进程加载目标应用的代码和资源。
②system_server进程接收到请求后,通过socket向zygote进程发送创建进程的请求
③Zygote进程fork出新的子进程,即App进程
- 应用进程初始化
④App进程,通过Binder IPC向sytem_server进程发起attachApplication请求
⑤system_server进程在收到请求后,进行一系列准备工作后,再通过binder IPC向App进程发送scheduleLaunchActivity请求
⑥App进程的binder线程(ApplicationThread)在收到请求后,通过handler向主线程发送LAUNCH_ACTIVITY消息
⑦主线程在收到Message后,通过反射机制创建目标Activity,并回调Activity.onCreate()等方法
- UI渲染完成
⑧App正式启动,开始进入Activity生命周期,执行完onCreate/onStart/onResume方法,UI渲染结束后便可以看到App的主界面,通过SurfaceFlinger合成帧并显示。
核心进程及通信方式
(1) Launcher进程 → System Server(AMS/PMS)
- 通信方式:Binder(基于AIDL)
- 原因:
- Binder是Android默认的高效IPC机制,支持同步调用和复杂数据传输。
- Launcher与AMS/PMS属于不同进程,需跨进程调用系统服务。
(2) System Server(AMS) → Zygote
- 通信方式:Unix Domain Socket
- 原因:
- Zygote在开机时通过Socket监听请求(避免依赖Binder的递归初始化问题)。
- Socket适合单向、批量数据传输(如传递应用启动参数)。
(3) System Server(AMS) → 应用进程
- 通信方式:Binder
- 原因:
- AMS需要持续管理应用生命周期(如暂停/销毁Activity),Binder支持双向通信。
- 应用进程通过
IApplicationThread
(Binder接口)回调AMS。
(4) 应用进程 → SurfaceFlinger
- 通信方式:Binder + Shared Memory(ASHMEM)
- 原因:
- Binder传递UI元数据(如窗口属性)。
- Shared Memory(通过
Surface
)高效传输图像数据,避免拷贝开销。
热启动流程
- 用户点击应用图标或返回应用
- Launcher或Recent Tasks通过
startActivity()
发起启动请求。
- System Server(AMS)检查进程状态
- AMS发现目标应用进程仍存活,直接复用该进程。
- 恢复Activity栈
- AMS通过Binder通知应用进程恢复之前的Activity(而非创建新实例)。
- UI渲染
- 应用主线程重新执行
onResume()
、测量/布局/绘制,并显示界面。
深入理解安卓应用程序启动流程
还是以冷启动来看,copy东方玻璃大佬的文章
以上流程的核心可总结为三个部分,后续将围绕这三部分展开:
- 创建应用程序进程
- 创建Application
- 启动根Activity
创建应用程序进程简介
要想启用一个Android应用程序,要保证该程序所需的应用程序进程存在.
当点击应用程序图标后,触发Launcher.onClick方法,经过一系列方法调用后,在ActivityStackSupervisor.startSpecificActivityLocked中会判断当前应用程序进程是否存在.
若不存在则调用AMS代理类ActivityManagerProxy的startProcessLocked请求AMS创建应用程序进程,AMS接收Launcher的请求后又向Zygote发送请求.
这一过程可分为两部分:
- AMS向Zygote发送启动应用程序进程的请求
- Zygote接收AMS的请求并创建应用程序进程
AMS向Zygote发送启动应用程序进程的请求的流程如下:
Launcher请求AMS,AMS请求Zygote,通过ZygoteInit.main进入Zygote

Zygote接收AMS的请求并创建应用程序进程的流程如下:
- 在进行一系列处理后进入ZygoteConnection.handleChildProc,该函数内部配置子进程的初始环境后并调用ZygoteInit.zygoteInit初始化应用程序进程
- ZygoteInit.zygoteInit中调用ZygoteInit.nativeZygoteInit启动了应用程序进程的Binder线程池,使得进程可以进行Binder通讯,之后调用RuntimeInit.applicationInit
- Binder 线程池:Server 端通过线程池处理多个 Client 的并发请求,避免主线程阻塞
- RuntimeInit调用invokeStaticMain并抛出Zygote.MethodAndArgsCaller异常,经过异常处理清空设置过程中的堆栈帧后,调用主线程管理类ActivityThread的main方法,至此,应用程序进程被成功创建

创建Application简介
ActivityThread.main进行部分初始化配置后,创建并启动主线程消息循环管理类Looper用于进行消息处理,并且调用attach方法通知AMS附加自身ApplicationThread类.
AMS中通过ApplicationThread的代理类IApplicationThread发送BIND_APPLICATION消息到应用程序的消息队列.
之后应用程序主线程管理类ActivityThread的handleMessage处理该消息,并调用handleBindApplication创建Application并绑定,主要执行以下4个步骤:
- ActivityThread.getPackageInfoNoCheck
- LoadedApk:每个应用对应一个LoadedApk实例,包含:
- APK 的资源路径、证书信息、权限等
- 应用的
ClassLoader
(默认是PathClassLoader
) - 缓存的资源和类信息
创建LoadedApk对象,设置ApplicationInfo和ClassLoader并加入mPackages中,该对象是应用程序apk包的管理类
- ContextImpl.createAppContext
创建应用程序的上下文环境Context类
- LoadedApk.makeApplication(创建 Application 实例)
创建Application,并调用Application.attachBaseContext方法
- Instrumentation.callApplicationOnCreate
调用Application.onCreate方法
至此,Application创建完成,以上流程如图所示:

启动根Activity简介
经过以上步骤后,创建了应用程序进程和对应的Application,回到Launcher请求AMS过程,在ActivityStackSupervisor.startSpecificActivityLocked中调用了ActivityStackSupervisor.realStartActivityLocked,其内部通过调用ApplicationThread.scheduleLaunchActivity通知应用程序启动Activity.
ApplicationThread通过sendMessage向H类(应用程序进程中主线程的消息管理类)发送H.LAUNCH_ACTIVITY消息,H.handleMessage接收到消息后调用ActivityThread.handleLaunchActivity将控制权转移给ActivityThread.
handleLaunchActivity调用performLaunchActivity执行启动Activity的步骤:
- 获取Activity信息类ActivityInfo
- 获取Apk文件描述类LoadedApk
- 为Activity创建上下文环境
- 获取Activity完整类名并通过ClassLoader创建Activity实例
- 调用LoadedApk.makeApplication
这一步需要解释,Application类是Android的应用程序描述类,每个应用程序只有一个全局单例的Application.
此处调用makeApplication时,由于ActivityThread.main中已经创建Application,所以会直接返回已创建的Application.
而performLaunchActivity用于启动任意Activity,根Activity必定使用ActivityThread.main创建的Application,但其他Activity可能在子进程中运行,所以此处的调用主要用于处理一般Activity.
- 调用Activity.attach初始化Activity
- 调用Instrumentation.callActivityOnCreate启动Activity
以上流程如图所示:

经过以上步骤后,安卓应用程序正式启动(根Activity启动),其中最值得关注的便是ActivityThread,Application和LoadedApk类.
- ActivityThread是安卓应用程序进程的主线程管理类
保存了很多关键信息,通过该类可以反射获取应用程序进程的Application和LoadedApk.
- Application用于描述当前的应用程序
应用程序启动过程中,Application实例是最先创建的,早于应用程序启动以及任何Activity或Service,它的生命周期是整个应用程序中最长的,等于应用程序的生命周期.
安卓应用程序开发时,可通过继承该类并重写attachBaseContext和onCreate方法进行部分资源的初始化配置.如果被保护程序没有指定自定义的Application,使用系统创建的默认Application即可;如果存在自定义的Application,则脱壳程序需要替换.
- LoadedApk用于描述当前应用程序对应的APK文件
其mClassLoader字段保存了当前APK对应的类加载器,mApplication字段保存了当前Application.
- 作者:Sh4d0w
- 链接:https://sh4d0w.blog//article/20150fad-5ffd-8062-afc4-fd7987453c17
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。