本文将深入Android源码(基于Android 12),解析从用户点击桌面图标到应用完全启动的全过程,揭示系统服务、Zygote进程、Binder通信等核心机制如何协同工作。
一、起点:Launcher发起启动请求当用户点击应用图标时,Launcher作为系统桌面应用,通过startActivity()启动目标应用:
代码语言:txt复制// packages/apps/Launcher3/src/com/android/launcher3/Launcher.java
public boolean startActivitySafely(View v, Intent intent, ItemInfo item) {
// ...
startActivity(intent, optsBundle);
}这里的Intent包含关键信息:component = com.example.app/.MainActivity
二、穿越进程边界:向系统服务发起请求Launcher通过Binder IPC调用ActivityTaskManagerService(ATMS):
代码语言:txt复制// frameworks/base/core/java/android/app/Activity.java
public void startActivity(Intent intent) {
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(),
intent, -1 /* requestCode */);
}
// frameworks/base/core/java/android/app/Instrumentation.java
public ActivityResult execStartActivity(...) {
int result = ActivityTaskManager.getService().startActivity(...);
}ActivityTaskManager.getService()返回的是ATMS的Binder代理对象。
三、系统进程的调度枢纽:ActivityTaskManagerServiceATMS在系统进程(system_server)中处理请求:
代码语言:txt复制// frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
public final int startActivity(...) {
return startActivityAsUser(...);
}
private int startActivityAsUser(...) {
// 1. 验证权限
// 2. 创建ActivityRecord
// 3. 获取目标进程
ProcessRecord app = mProcessMap.getProcess(...);
if (app == null) {
// 需要启动新进程
mAtmInternal.startProcessAsync(...);
}
}关键对象创建:
ActivityRecord:代表一个Activity实例ProcessRecord:代表应用进程状态Task:管理Activity的栈四、Zygote孵化新进程当目标进程不存在时,ATMS通过ProcessList向Zygote发起fork请求:
代码语言:txt复制// frameworks/base/services/core/java/com/android/server/am/ProcessList.java
final Process.ProcessStartResult startResult = startProcess(...);
private Process.ProcessStartResult startProcess(...) {
return Process.start(entryPoint, ...);
}
// frameworks/base/core/java/android/os/Process.java
public static ProcessStartResult start(...) {
return zygoteProcess.start(...);
}Zygote进程通过socket接收请求并fork:
代码语言:txt复制// frameworks/base/cmds/app_process/app_main.cpp
int main(int argc, char* const argv[]) {
// ...
if (zygote) {
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
}
}
// frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String argv[]) {
// 监听socket
runSelectLoop(abiList);
}
private static void runSelectLoop() {
// 接受AMS请求
ZygoteConnection connection = peers.get(fdIndex);
final Runnable command = connection.processCommand();
}fork完成后,新进程执行ActivityThread.main()入口。
五、应用进程初始化:ActivityThread与主线程当Zygote fork出新进程后,会执行ActivityThread.main()方法:
代码语言:txt复制// frameworks/base/core/jni/AndroidRuntime.cpp
void AndroidRuntime::start(const char* className, ...) {
// 通过JNI调用ZygoteInit的main方法
env->CallStaticVoidMethod(startClass, startMeth, strArray);
}代码语言:txt复制// frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static Runnable forkAndSpecialize(...) {
int pid = Zygote.forkAndSpecialize(...);
if (pid == 0) {
// 在子进程中执行
return handleChildProc(parsedArgs, ...);
}
}
private static Runnable handleChildProc(String[] args, ...) {
// 最终调用ActivityThread的main方法
return ZygoteInit.zygoteInit(...);
}
static Runnable zygoteInit(...) {
RuntimeInit.commonInit();
return RuntimeInit.applicationInit(...);
}
protected static Runnable applicationInit(...) {
// 通过反射调用ActivityThread.main()
return findStaticMain(args.startClass, args.startArgs);
}执行流程:
Zygote通过fork()创建新进程子进程执行handleChildProc()通过RuntimeInit.applicationInit()反射调用最终执行ActivityThread.main()新进程从ActivityThread.main()开始执行:
代码语言:txt复制// frameworks/base/core/java/android/app/ActivityThread.java
public static void main(String[] args) {
Looper.prepareMainLooper(); // 创建主线程Looper
ActivityThread thread = new ActivityThread();
thread.attach(false); // 关键:连接系统服务
Looper.loop(); // 启动消息循环
}attach()方法建立与AMS的连接:
代码语言:txt复制private void attach(boolean system) {
final IActivityManager mgr = ActivityManager.getService();
mgr.attachApplication(mAppThread); // mAppThread是ApplicationThread对象
}此处通过Binder调用ATMS的attachApplication()。
六、双向通信桥梁:ApplicationThreadApplicationThread是ActivityThread的内部类,作为ATMS回调应用进程的Binder接口:
代码语言:txt复制final ApplicationThread mAppThread = new ApplicationThread();
// ActivityThread内部类
private class ApplicationThread extends IApplicationThread.Stub {
public final void bindApplication(...) {
sendMessage(H.BIND_APPLICATION, data);
}
public final void scheduleLaunchActivity(...) {
sendMessage(H.LAUNCH_ACTIVITY, r);
}
}应用进程使用H(Handler)处理消息:
代码语言:txt复制class H extends Handler {
public void handleMessage(Message msg) {
case BIND_APPLICATION:
handleBindApplication(data);
case LAUNCH_ACTIVITY:
handleLaunchActivity(r);
}
}七、应用级初始化:创建ApplicationhandleBindApplication()触发应用级初始化:
代码语言:txt复制// frameworks/base/core/java/android/app/ActivityThread.java
private void handleBindApplication(AppBindData data) {
// 1. 创建LoadedApk(代表加载的APK)
final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
appContext.getClassLoader(), false, true, false);
// 2. 创建ContextImpl
final ContextImpl appContext = ContextImpl.createAppContext(this, pi);
// 3. 实例化Application
Application app = pi.makeApplication(forceDefaultAppClass, instr);
// 4. 安装ContentProviders
if (!data.restrictedBackupMode) {
installContentProviders(app, data.providers);
}
// 5. 回调Application.onCreate()
mInstrumentation.callApplicationOnCreate(app);
}关键步骤:
通过ClassLoader加载APK资源创建应用级上下文反射实例化自定义Application类触发应用初始化回调Application.attachBaseContext()何时调用?
在创建Application实例后立即调用:
代码语言:txt复制// frameworks/base/core/java/android/app/LoadedApk.java
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
// 1. 创建Application实例
Application app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
return app;
}
// frameworks/base/core/java/android/app/Instrumentation.java
public Application newApplication(ClassLoader cl, String className, Context context) {
Application app = getFactory(context).instantiateApplication(cl, className);
// 关键调用
app.attach(context);
return app;
}
// frameworks/base/core/java/android/app/Application.java
final void attach(Context context) {
attachBaseContext(context); // 调用Application的protected方法
mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
}八、Activity实例化与生命周期收到LAUNCH_ACTIVITY消息后,创建目标Activity:
代码语言:txt复制// frameworks/base/core/java/android/app/ActivityThread.java
private Activity handleLaunchActivity(ActivityClientRecord r) {
final Activity a = performLaunchActivity(r, null);
return a;
}
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// 1. 创建Activity实例
Activity activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
// 2. 创建Application(如果尚未创建)
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
// 3. 关联Context
Context appContext = createBaseContextForActivity(r, activity);
activity.attach(appContext, ...);
// 4. 回调onCreate()
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
return activity;
}九、全流程关键节点时序图
十、关键技术点解析1、Zygote预加载机制共享库:/system/framework/android.jar资源:预加载res/values等公共资源类:850+个预加载类(通过preload-classes配置)2、Binder线程池管理代码语言:txt复制// ProcessState.cpp初始化时
mThreadPoolStarted = true
spawnPooledThread(true) // 启动首个Binder线程3、资源隔离机制每个应用进程持有独立的AssetManager通过ResourcesKey实现资源分区资源覆盖(Overlay)通过AssetManager.addOverlayPath()实现4、类加载优化代码语言:txt复制// LoadedApk.java
public ClassLoader getClassLoader() {
if (mClassLoader == null) {
mClassLoader = ApplicationLoaders.getDefault().getClassLoader(
zip, libPath, parent, isBundledApp);
}
}5、ApplicationThread的Binder本质代码语言:txt复制// IApplicationThread.aidl
interface IApplicationThread {
void bindApplication(...);
void scheduleLaunchActivity(...);
// 共40+个系统回调接口
}6、attachBaseContext的特殊性唯一在Application构造函数后立即执行的方法此时ContentProvider已初始化完成但其他组件(Activity/Service)尚未创建7、ContentProvider的初始化陷阱代码语言:txt复制// 错误示例:在Application中初始化依赖ContentProvider的数据
public class MyApp extends Application {
public void onCreate() {
super.onCreate();
// 此时userProvider可能未初始化完成!
User user = userProvider.getCurrentUser();
}
}解决方案:使用ContentResolver惰性查询8、Activity创建的多阶段attach代码语言:txt复制// Activity.java
final void attach(Context context, ...) {
attachBaseContext(context); // 1. 关联上下文
mWindow = new PhoneWindow(this); // 2. 创建窗口
mUiThread = Thread.currentThread(); // 3. 绑定UI线程
// 4. 关联WindowManager
mWindow.setWindowManager(wm, ...);
}十一、性能优化实践1、启动阶段组件初始化优化代码语言:txt复制// 优化ContentProvider初始化
android:name=".MyProvider" android:authorities="com.example.provider" android:initOrder="100" /> 2、Multidex处理的正确位置代码语言:txt复制protected void attachBaseContext(Context base) { super.attachBaseContext(base); // 必须在此处初始化Multidex MultiDex.install(this); }3、延迟初始化策略代码语言:txt复制// 使用延迟加载占位 public void onCreate() { getMainExecutor().execute(() -> { // 延迟初始化非关键组件 initHeavyLibrary(); }); }4、冷启动耗时分解代码语言:txt复制# 使用adb分析 adb shell am start -W -S com.example.app/.MainActivityTotalTime:包括Zygote fork+初始化+Activity渲染WaitTime:包含系统调度延迟十二、总结:Android应用启动的哲学Android应用启动流程体现了以下设计思想: 进程隔离:通过Zygote fork保证进程间资源隔离异步通信:基于Binder和Handler实现跨进程协作统一生命周期:通过系统服务集中管理组件状态资源分层:系统资源与应用资源分离加载懒加载机制:按需创建组件(如BroadcastReceiver)理解这些底层机制,不仅能优化应用启动性能,更能帮助开发者设计出符合Android设计哲学的应用程序架构。