
本文将深入Android源码(基于Android 12),解析从用户点击桌面图标到应用完全启动的全过程,揭示系统服务、Zygote进程、Binder通信等核心机制如何协同工作。
当用户点击应用图标时,Launcher作为系统桌面应用,通过startActivity()启动目标应用:
// 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):
// 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代理对象。
ATMS在系统进程(system_server)中处理请求:
// 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(...);
}
}关键对象创建:
当目标进程不存在时,ATMS通过ProcessList向Zygote发起fork请求:
// 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:
// 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()入口。
当Zygote fork出新进程后,会执行ActivityThread.main()方法:
// frameworks/base/core/jni/AndroidRuntime.cpp
void AndroidRuntime::start(const char* className, ...) {
// 通过JNI调用ZygoteInit的main方法
env->CallStaticVoidMethod(startClass, startMeth, strArray);
}// 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);
}执行流程:
fork()创建新进程handleChildProc()RuntimeInit.applicationInit()反射调用ActivityThread.main()新进程从ActivityThread.main()开始执行:
// 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的连接:
private void attach(boolean system) {
final IActivityManager mgr = ActivityManager.getService();
mgr.attachApplication(mAppThread); // mAppThread是ApplicationThread对象
}此处通过Binder调用ATMS的attachApplication()。
ApplicationThread是ActivityThread的内部类,作为ATMS回调应用进程的Binder接口:
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)处理消息:
class H extends Handler {
public void handleMessage(Message msg) {
case BIND_APPLICATION:
handleBindApplication(data);
case LAUNCH_ACTIVITY:
handleLaunchActivity(r);
}
}handleBindApplication()触发应用级初始化:
// 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.attachBaseContext()何时调用?
在创建Application实例后立即调用:
// 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;
}收到LAUNCH_ACTIVITY消息后,创建目标Activity:
// 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;
}
/system/framework/android.jarres/values等公共资源preload-classes配置)// ProcessState.cpp初始化时
mThreadPoolStarted = true
spawnPooledThread(true) // 启动首个Binder线程AssetManagerResourcesKey实现资源分区AssetManager.addOverlayPath()实现// LoadedApk.java
public ClassLoader getClassLoader() {
if (mClassLoader == null) {
mClassLoader = ApplicationLoaders.getDefault().getClassLoader(
zip, libPath, parent, isBundledApp);
}
}// IApplicationThread.aidl
interface IApplicationThread {
void bindApplication(...);
void scheduleLaunchActivity(...);
// 共40+个系统回调接口
}Application构造函数后立即执行的方法// 错误示例:在Application中初始化依赖ContentProvider的数据
public class MyApp extends Application {
public void onCreate() {
super.onCreate();
// 此时userProvider可能未初始化完成!
User user = userProvider.getCurrentUser();
}
}ContentResolver惰性查询// 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, ...);
}// 优化ContentProvider初始化
<provider
android:name=".MyProvider"
android:authorities="com.example.provider"
android:initOrder="100" /> <!-- 调整初始化顺序 -->protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
// 必须在此处初始化Multidex
MultiDex.install(this);
}// 使用延迟加载占位
public void onCreate() {
getMainExecutor().execute(() -> {
// 延迟初始化非关键组件
initHeavyLibrary();
});
}# 使用adb分析
adb shell am start -W -S com.example.app/.MainActivityAndroid应用启动流程体现了以下设计思想:
理解这些底层机制,不仅能优化应用启动性能,更能帮助开发者设计出符合Android设计哲学的应用程序架构。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。