Activity启动流程分析

本文章源码基于API:29

startActivity函数调用

  1. Activity
    startActivity() -> startActivityForResult()
  2. Instrumentation
    execStartActivity() -> ActivityTaskManagerService:startActivity()
    ⚠️ 切换进程:从上一个activity的进程切换到ActivityTaskManagerService进程
  3. ActivityTaskManagerService
    startActivityAsUser() -> ActivityStarter:execute() -> startActivityMayWait()
  4. ActivityStarter
    startActivity() -> startActivityUnchecked() -> RootActivityContainer:resumeFocusedStacksTopActivities()
    调用多个startActivity方法后,来到了startActivityUnchecked方法。
  5. ActivityStack
    resumeTopActivityUncheckedLocked() -> resumeTopActivityInnerLocked() -> ActivityStackSupervisor:startSpecificActivityLocked()
  6. ActivityStackSupervisor
    realStartActivityLocked() -> addCallback(LaunchActivityItem) -> ClientLifecycleManager:scheduleTransaction()
//添加一个启动activity的ClientTransactionItem
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
        System.identityHashCode(r), r.info,
        // TODO: Have this take the merged configuration instead of separate global
        // and override configs.
        mergedConfiguration.getGlobalConfiguration(),
        mergedConfiguration.getOverrideConfiguration(), r.compat,
        r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
        r.icicle, r.persistentState, results, newIntents,
        dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
                r.assistToken));

// 执行LaunchActivityItem的schedule方法,然后回到ApplicationThread中,开始调用clientTransaction中的callback(LaunchActivityItem)
mService.getLifecycleManager().scheduleTransaction(clientTransaction);

启动进程

  1. 在startSpecificActivityLocked方法中
// Is this activity's application already running?
final WindowProcessController wpc =
        mService.getProcessController(r.processName, r.info.applicationInfo.uid);

首先判断activity的application是否存在,如果不存着,则需要启动一个进程,所以,在首次打开app的时候,会先去创建app需要的进程。下次再打开一个activity,就直接调用realStartActivityLocked()
⚠️ 首次启动需要创建进程

  1. ActivityStackSupervisor:startSpecificActivityLocked()
// Post message to start process to avoid possible deadlock of calling into AMS with the
// ATMS lock held.
final Message msg = PooledLambda.obtainMessage(
        ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
        r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
mService.mH.sendMessage(msg);

通过handler告诉ActivityManagerInternal的子类(ActivityManagerService的内部类LocalService) -> startProcess() -> startProcessLocked() -> ProcessList:startProcessLocked()

  1. ProcessList:startProcessLocked()
//开启进程
final Process.ProcessStartResult startResult = startProcess(app.hostingRecord,
        entryPoint, app, app.startUid, gids, runtimeFlags, mountExternal,
        app.seInfo, requiredAbi, instructionSet, invokeWith, app.startTime);
  1. ProcessList:startProcess()
if (hostingRecord.usesWebviewZygote()) {
    startResult = startWebView(entryPoint,
            app.processName, uid, uid, gids, runtimeFlags, mountExternal,
            app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
            app.info.dataDir, null, app.info.packageName,
            new String[] {PROC_START_SEQ_IDENT + app.startSeq});
} else if (hostingRecord.usesAppZygote()) {
    final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);

    startResult = appZygote.getProcess().start(entryPoint,
            app.processName, uid, uid, gids, runtimeFlags, mountExternal,
            app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
            app.info.dataDir, null, app.info.packageName,
            /*useUsapPool=*/ false,
            new String[] {PROC_START_SEQ_IDENT + app.startSeq});
} else {
    startResult = Process.start(entryPoint,
            app.processName, uid, uid, gids, runtimeFlags, mountExternal,
            app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
            app.info.dataDir, invokeWith, app.info.packageName,
            new String[] {PROC_START_SEQ_IDENT + app.startSeq});
}

判断通过何种方式开启进程。

  1. Process:start() -> startVisZygote() -> openZygoteSocketIfNeeded() -> attemptConnectionToPrimaryZygote()
//startVisZygote()方法中
synchronized(mLock) {
    // The USAP pool can not be used if the application will not use the systems graphics
    // driver.  If that driver is requested use the Zygote application start path.
    return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
                                      useUsapPool,
                                      argsForZygote);
}
//openZygoteSocketIfNeeded()方法中
try {
    attemptConnectionToPrimaryZygote();

    if (primaryZygoteState.matches(abi)) {
        return primaryZygoteState;
    }


通知创建进程,之后就是ActivityThread的启动了。

启动application

  1. ActivityThread.main() 初始化Looper和ActivityThread
//初始化looper
Looper.prepareMainLooper();
//创建ActivityThread类,同时会创建ApplicationThread类
ActivityThread thread = new ActivityThread();
//调用attach方法
thread.attach(false, startSeq);
  1. ActivityThread:attach()
final IActivityManager mgr = ActivityManager.getService();
try {
    mgr.attachApplication(mAppThread, startSeq);
} catch (RemoteException ex) {
    throw ex.rethrowFromSystemServer();
}

调用ActivityManagerService的attachApplication
⚠️ 切换进程,调用ActivityManagerService的代理类

  1. ActivityManagerService :attachApplication() -> attachApplicationLocked()
//ActivityManagerService 最终调用attachApplicationLocked()
//创建了ProcessRecord,用来记录进程的信息
ProcessRecord app;
if (pid != MY_PID && pid >= 0) {
    synchronized (mPidsSelfLocked) {
        app = mPidsSelfLocked.get(pid);
    }
…

//调用传入ApplicationThread的bindApplication方法
thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
        null, null, null, testMode,
        mBinderTransactionTrackingEnabled, enableTrackAllocation,
        isRestrictedBackupMode || !normalMode, app.isPersistent(),
        new Configuration(app.getWindowProcessController().getConfiguration()),
        app.compat, getCommonServicesLocked(app.isolated),
        mCoreSettingsObserver.getCoreSettingsLocked(),
        buildSerial, autofillOptions, contentCaptureOptions);
  1. ApplicationThread把AMS传过来的参数记录下来,利用ActivityThread的hanlder把数据发送出去。
//ApplicationThread.bindApplication()方法

AppBindData data = new AppBindData();
data.processName = processName;
data.appInfo = appInfo;
data.providers = providers;
data.instrumentationName = instrumentationName;
data.instrumentationArgs = instrumentationArgs;
data.instrumentationWatcher = instrumentationWatcher;
data.instrumentationUiAutomationConnection = instrumentationUiConnection;
data.debugMode = debugMode;
data.enableBinderTracking = enableBinderTracking;
data.trackAllocation = trackAllocation;
data.restrictedBackupMode = isRestrictedBackupMode;
data.persistent = persistent;
data.config = config;
data.compatInfo = compatInfo;
data.initProfilerInfo = profilerInfo;
data.buildSerial = buildSerial;
data.autofillOptions = autofillOptions;
data.contentCaptureOptions = contentCaptureOptions;
sendMessage(H.BIND_APPLICATION, data);

⚠️ 回到ApplicationThread中

  1. ActivityThread:Handler.handleMessage()
case BIND_APPLICATION:
    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, “bindApplication”);
    AppBindData data = (AppBindData)msg.obj;
    handleBindApplication(data);
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    break;
  1. handler接收到消息后处理 msg.what = /BIND_APPLICATION/
    VMRuntime会对当前线程进行注册,然后做一些记录和赋值。
//handleBindApplication()方法中

//VMRuntime注册
VMRuntime.registerSensitiveThread();

//创建上下文()
final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);

//创建Application
Application app;
app = data.info.makeApplication(data.restrictedBackupMode, null);

//调用application的onCreate方法
mInstrumentation.callApplicationOnCreate(app);

⚠️ 至此,app的Application就启动了。。。

启动activity

  1. 回到AMS的attachApplicationLocked()方法中,在通知ApplicationThread启动Application后(bindApplication方法),后面就进行activity的创建
//ActivityManagerService.attachApplicationLocked()
// See if the top visible activity is waiting to run in this process…
if (normalMode) {
    try {
        didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
    } catch (Exception e) {
        Slog.wtf(TAG, “Exception thrown launching activities in “ + app, e);
        badApp = true;
    }
}
  1. mAtmInternal的实现类是ActivityTaskManagerService的内部类LocalService
//ActivityTaskManagerService.LocalService.attachApplication()
@Override
public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
    synchronized (mGlobalLockWithoutBoost) {
        return mRootActivityContainer.attachApplication(wpc);
    }
}
  1. RootActivityContainer:attachApplication()
if (mStackSupervisor.realStartActivityLocked(activity, app,
        top == activity /* andResume */, true /* checkConfig */)) {
    didSomething = true;
}

调用ActivityStackSupervisor:realStartActivityLocked()

  1. ActivityStackSupervisor:realStartActivityLocked()
//添加一个启动activity的ClientTransactionItem
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
        System.identityHashCode(r), r.info,
        // TODO: Have this take the merged configuration instead of separate global
        // and override configs.
        mergedConfiguration.getGlobalConfiguration(),
        mergedConfiguration.getOverrideConfiguration(), r.compat,
        r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
        r.icicle, r.persistentState, results, newIntents,
        dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
                r.assistToken));

// 执行LaunchActivityItem的schedule方法,然后回到ApplicationThread中,开始调用clientTransaction中的callback(LaunchActivityItem)
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
  1. 通过ClientLifecycleManager调用ClientTransaction的schedule()
//调用schedule方法
transaction.schedule();
//ClientTransaction
public void schedule() throws RemoteException {
      //mClient 是ApplicationThread的代理类
    mClient.scheduleTransaction(this);
}

⚠️ 切换进程:调用scheduleTransaction()后,切换到了ApplicationThread进程。

  1. ApplicationThread进程:
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
    ActivityThread.this.scheduleTransaction(transaction);
}

ActivityThread.this在当前子类中没有这个方法,需要去父类查看

  1. ActivityThread的父类 ClientTransactionHandler
void scheduleTransaction(ClientTransaction transaction) {
    transaction.preExecute(this);
    sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}

发送消息通知ActivityThread处理transaction

  1. ActivityThread的Handler中
//Handler.handleMessage()
case EXECUTE_TRANSACTION:
    final ClientTransaction transaction = (ClientTransaction) msg.obj;
    mTransactionExecutor.execute(transaction);
    if (isSystem()) {
        // Client transactions inside system process are recycled on the client side
        // instead of ClientLifecycleManager to avoid being cleared before this
        // message is handled.
        transaction.recycle();
    }
    // TODO(lifecycler): Recycle locally scheduled transactions.
    break;
  1. TransactionExecutor
    execute() -> executeCallbacks()
//TODO 1
executeCallbacks(transaction);

//TODO 2
executeLifecycleState(transaction);

executeCallbacks()处理addCallback中添加的LaunchActivityItem
executeCallbacks() -> LaunchActivityItem:execute()

  1. LaunchActivityItem
@Override
public void execute(ClientTransactionHandler client, IBinder token,
        PendingTransactionActions pendingActions) {
    Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, “activityStart”);
    ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
            mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
            mPendingResults, mPendingNewIntents, mIsForward,
            mProfilerInfo, client, mAssistToken);
    //client就是ActivityThread
    client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
    Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}

上面已经知道ActivityThread是ClientTransactionHandler的子类,所以handleLaunchActivity方法又回到了ActivityThread

  1. ActivityThread:handleLaunchActivity() -> performLaunchActivity()
//内部通过反射的方式创建了activity
final Activity a = performLaunchActivity(r, customIntent);

通过performLaunchActivity方法,内部反射的方式创建出activity

  1. ActivityThread:performLaunchActivity()
//反射创建activity
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
        cl, component.getClassName(), r.intent);

//得到application
Application app = r.packageInfo.makeApplication(false, mInstrumentation);

//activity和application关联
activity.attach(appContext, this, getInstrumentation(), r.token,
        r.ident, app, r.intent, r.activityInfo, title, r.parent,
        r.embeddedID, r.lastNonConfigurationInstances, config,
        r.referrer, r.voiceInteractor, window, r.configCallback,
        r.assistToken);

//调用activity的onCreate
if (r.isPersistable()) {
    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
    mInstrumentation.callActivityOnCreate(activity, r.state);
}
  1. Instrumentation:callActivityOnCreate()
public void callActivityOnCreate(Activity activity, Bundle icicle) {
    prePerformCreate(activity);
    activity.performCreate(icicle);
    postPerformCreate(activity);
}
  1. Activity:performCreate() -> onCreate()
    调用activity的onCreate方法

总结:

步骤1~6(startActivity函数调用)

startActivity函数的调用,通过Instrumentation 通知ActivityTaskManagerService对activity进行包装和校验。然后通知ActivityStackSupervisor真正启动activity

步骤7~12(启动进程)

ActivityStackSupervisor启动activity之前,需要判断activity的进程是否存在,如果不存在,则需要从zygote进程中fork出一个子进程。

步骤13~18(启动application)

这里是最熟悉的app启动入口ActivityThread。进程启动后,就会进入main方法,初始化application

步骤19~32(启动activity)

启动application后,AMS就会启动activity,其中会创建一个LaunchActivityItem,通知ApplicationThread接收,在ActivityThread的handler中处理LaunchActivityItem的任务。反射创建出activity后,与application进行关联,最后调用activity的生命周期onCreate。

参考:

Android 9.0 APP 启动流程分析 (进程创建 ,ActivityThread 创建 ,Application创建,Activity的创建,)

Android进阶(三):Application启动过程(最详细&最简单) - 简书

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,063评论 6 510
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,805评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,403评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,110评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,130评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,877评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,533评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,429评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,947评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,078评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,204评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,894评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,546评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,086评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,195评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,519评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,198评论 2 357