Activity启动流程分析

作者: space0o0 | 来源:发表于2020-02-25 16:09 被阅读0次

本文章源码基于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启动过程(最详细&最简单) - 简书

相关文章

网友评论

    本文标题:Activity启动流程分析

    本文链接:https://www.haomeiwen.com/subject/brntchtx.html