2010世界杯主题曲_世界杯非洲预选赛 - fsyxyy.com

从源码解析Android应用启动全流程:从点击图标到Activity渲染的深度剖析

本文将深入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设计哲学的应用程序架构。

槐连豆的药方
vip客户管理与维护要怎么做


最新发表

友情链接