【原理】Activity的启动流程(api 29)

1 闲话

喜欢读源码的同学应该早就注意到了,android api28以后,Activity的启动流程改变了许多,如android 28以后,ActivityThread中已经删除掉了LAUNCH_ACTIVITY的标签,而且也将一些逻辑单独提出来放在了一些新的类里面。由于我只是关注了它从ActivityThread的main以及startActivity走到最终调用Activity的生命周期,没有仔细阅读其细节,所以本文主要讲这个流程,细节先不写。

2 从ActivityThread到Activity的onCreate调用链

先给出流程描述:

  1. 我们启动应用程序时,首先会启动的是zygote进程,然后由该进程
    启动系统服务以及其它服务等。当一个应用进程启动后,就会加载
    在AndroidManifest.xml里面设置的默认加载的Activity。此时的
    加载入口是ActivityThread里面的main方法。该方法是整个程序的
    入口。在该方法里,首先会创造一个主线程相关的消息机制,即调用
    Looper.prepareMainLooper方法,然后创建一个ActivityThread对象,
    并调用ActivityThread里的attach方法。最后调用Looper.prepare来
    开启消息循环。

  2. 在attach方法中,首先判断是否是系统应用,如果是系统应用会走
    另外一套逻辑,我们关注的是不是系统应用这一部分。在不是系统应用
    这一部分的代码逻辑中,首先会通过AIDL来获取ActivityManagerService
    的对象,然后调用ActivityManagerService里面的attachApplication.

  3. 在ActivityManagerService的attachApplication中,会调用ActivityManagerService
    下的attachApplicationLocked.

  4. attachApplicationLocked方法比较长,主要做看以下几件事:

    (1)调用ActivityThread的bindApplication方法启动Application
    (2)调用ActivityTaskManagerService的内部类LocalService的 attachApplicationLocked方法,该方法会调用RootActivityContainer的attachApplication方法,然后调用ActivityStackSupervisor的realStartActivityLocked方法去启动ActivityStack的栈顶的Activity
    (3)调用ActivityService的attachApplicationLocked方法启动当前进程的Service
    (4)检查是否有广播broadcast到这个application,如果有则广播

  5. 主要关注第2件事。最终会调用ActivityStackSupervisor的realStartActivityLocked方法,该方法会创建一个ClientTransaction对象,然后调用addCallback方法加入一个LaunchActivityItem对象(这个地方后面会用到),然后一系列的调用,最终会调用ApplicationThread的scheduleTransaction方法,该方法会调用ActivityThread的scheduleTransaction方法,在该方法中会调用sendMessage发送msg.what为EXCUTE_TRANSACTION的消息到ActivityThread的H中进行处理。在H中,会调用TransactionExecutor中的execute方法,该方法会调用executeCallbacks方法,而该方法中会调用LaunchActivityItem中的execute方法。然后该方法中会继续调用ClientTransactionHandler的handleLaunchActivity方法,该方法是ActivityThread的父类,最终调用的是ActivityThread的handleLaunchActivity方法,然后调用performLaunchActivity方法,最终会调用Instrumentation的callActivityOnCreate方法,最后会调用Activity的onCreate方法,到此Activity的启动大致结束。

流程图
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
我们都知道,ActivityThread的main方法是android程序的入口,先看看该源码:

    //ActivityThread.java  
	public static void main(String[] args) {
        //省略
        //创建主线程的Looper
        Looper.prepareMainLooper();
        //省略
        //创建ActivityThread对象
        ActivityThread thread = new ActivityThread();
        //attach是核心
        thread.attach(false, startSeq);
        //省略
        //启动消息循环
        Looper.loop();
    }

在ActivityThread的main方法里,会调用Looper.prepareMainLooper()来创建Looper及消息队列。然后创建ActivityThread对象,调用ActivityThread的attach方法,然后开启消息循环。这里主要关注点是attach方法,我们看看attach源码:

	//ActivityThread.java  
	final ApplicationThread mAppThread = new ApplicationThread();
	private void attach(boolean system, long startSeq) {
        //省略
        sCurrentActivityThread = this;
        mSystemThread = system;
        if (!system) {//如果不是系统级应用就走这里,一般app都不是系统级的
            android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
                                                    UserHandle.myUserId());
            RuntimeInit.setApplicationObject(mAppThread.asBinder());
            //通过AIDL获取ActivityManagerService
            final IActivityManager mgr = ActivityManager.getService();
            try {
                //重点
                mgr.attachApplication(mAppThread, startSeq);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
            //省略
        }

    }

对于我们自己的应用,一般都是非系统应用,所以会走上述if语句。在这里,它会创建一个ActivityManagerService对象,并调用ActivityManagerService的attachApplication方法,这是一个重要的方法,我们跟进去看看源码:

//ActivityManagerService
    @Override
    public final void attachApplication(IApplicationThread thread, long startSeq) {
        synchronized (this) {
            int callingPid = Binder.getCallingPid();
            final int callingUid = Binder.getCallingUid();
            final long origId = Binder.clearCallingIdentity();
            //重点
            attachApplicationLocked(thread, callingPid, callingUid, startSeq);
            Binder.restoreCallingIdentity(origId);
        }
    }

可以看到上述代码,它会继续调用ActivityManagerService的attachApplicationLocked方法,源码如下:

//ActivityManagerService
    @GuardedBy("this")
    private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid, int callingUid, long startSeq) {
        ProcessRecord app;//app的声明
        //省略
        //对app的初始化,可以看出app实际就是ProcessRecord类型
        if (app == null && startSeq > 0) {
            final ProcessRecord pending = mProcessList.mPendingStarts.get(startSeq);
            if (pending != null && pending.startUid == callingUid && pending.startSeq == startSeq
                    && mProcessList.handleProcessStartedLocked(pending, pid, pending
                            .isUsingWrapper(),
                            startSeq, true)) {
                app = pending;
            }
        }
        //省略
        app.makeActive(thread, mProcessStats);
        //省略
                // See if the top visible activity is waiting to run in this process...
        if (normalMode) {//普通模式
            try {
                //重点,app.getWindowProcessController()获得的是WindowProcessController对象,后面
                //会用到,需要找出它的初始化,app指的是ProcessRecord,在ProcessRecord里面可以对mWindowProcessController
                //赋值的地方只有ProcessRecord构造函数,所以查看当前方法里的ProcessRecord对象构造的地方,
                //我们主要找到mWindowProcessController设置Thread的地方,即mWindowProcessController.setThread地方,
                //在ProcessRecord里调用mWindowProcessController.setThread地方有:makeActive,makeInactive两个
                //方法。往上追述,可以发现这个thread是ApplicationThread
                
                //mAtmInternal初始化的地方分别是:ActivityManagerService构造函数,最终调用的是
                didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                badApp = true;
            }
        }
    }

在上述代码中,最终会走普通模式的if语句,最主要的是下面一行代码:

didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());

这里的mAtmInternal指的是LocalService,它继承自ActivityTaskManagerInternal,所以mAtmInternal.attachApplication最终调用的是LocalService的attachApplication,在LocalService的attachApplication里会调用RootActivityContainer.attachApplication。这里的app指的是ProcessRecord,app.getWindowProcessController()得到的值是WindowProcessController对象,这里主要关注的是WindowProcessController设置Thread的地方,往上追述发现该Thread其实是ApplicationThread对象。我们看一下LocalService的attachApplication源码:

//ActivityTaskManagerService内部类
final class LocalService extends ActivityTaskManagerInternal {
        @HotPath(caller = HotPath.PROCESS_CHANGE)
        @Override
        public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
            synchronized (mGlobalLockWithoutBoost) {
                //重点,mRootActivityContainer是RootActivityContainer类型
                return mRootActivityContainer.attachApplication(wpc);
            }
        }	
}

看看RootActivityContainer.attachApplication的源码

//RootActivityContainer
    boolean attachApplication(WindowProcessController app) throws RemoteException {
        final String processName = app.mName;
        boolean didSomething = false;
        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
            final ActivityDisplay display = mActivityDisplays.get(displayNdx);
            final ActivityStack stack = display.getFocusedStack();
            if (stack != null) {
                stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);
                final ActivityRecord top = stack.topRunningActivityLocked();
                final int size = mTmpActivityList.size();
                for (int i = 0; i < size; i++) {
                    final ActivityRecord activity = mTmpActivityList.get(i);
                    if (activity.app == null && app.mUid == activity.info.applicationInfo.uid
                            && processName.equals(activity.processName)) {
                        try {
                        //重点
                            if (mStackSupervisor.realStartActivityLocked(activity, app,
                                    top == activity /* andResume */, true /* checkConfig */)) {
                                didSomething = true;
                            }
                        } catch (RemoteException e) {
                            Slog.w(TAG, "Exception in new application when starting activity "
                                    + top.intent.getComponent().flattenToShortString(), e);
                            throw e;
                        }
                    }
                }
            }
        }
        if (!didSomething) {
            ensureActivitiesVisible(null, 0, false /* preserve_windows */);
        }
        return didSomething;
    }

mStackSupervisor.realStartActivityLocked这个方法是重点,我们进去看看

//ActivityStackSupervisor
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
            boolean andResume, boolean checkConfig) throws RemoteException {

				//省略

                // 往上追述可得,proc.getThread()得到的是ApplicationThread
                final ClientTransaction clientTransaction = ClientTransaction.obtain(
                        proc.getThread(), r.appToken);
    			//省略
    			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));
     			// Set desired final state.
                final ActivityLifecycleItem lifecycleItem;
                if (andResume) {
                    lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
                } else {
                    lifecycleItem = PauseActivityItem.obtain();
                }
    			//这个地方对mLifecycleStateRequest进行设置,后面会用到
				clientTransaction.setLifecycleStateRequest(lifecycleItem);
                // 重要的是这里
                mService.getLifecycleManager().scheduleTransaction(clientTransaction);
				//省略
    }

我们看看 mService.getLifecycleManager().scheduleTransaction(clientTransaction);的源码,这句最后调用了ClientLifecycleManager里面的scheduleTransaction方法,如下:

//ClientLifecycleManager.java里面
    void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
        final IApplicationThread client = transaction.getClient();
        //重点
        transaction.schedule();
        if (!(client instanceof Binder)) {
            // If client is not an instance of Binder - it's a remote call and at this point it is
            // safe to recycle the object. All objects used for local calls will be recycled after
            // the transaction is executed on client in ActivityThread.
            transaction.recycle();
        }
    }

上述代码最后调用的是ClientTransaction的schedule,我们来看看:

    public void schedule() throws RemoteException {
        mClient.scheduleTransaction(this);
    }

最后调用的是mClient的scheduleTransaction,这个mClient是哪来的呢?我们往上级返回查看ClientTransaction的创建地方,首先,它是上级方法scheduleTransaction传进来的(transaction),我们继续往上看,transaction是它所在方法的上级方法,即ActivityStackSupervisor的realStartActivityLocked里通过下面的方法得到的

ClientTransaction.obtain(proc.getThread(), r.appToken);

我们看看ClientTransaction的obtain方法:

    /** Obtain an instance initialized with provided params. */
    public static ClientTransaction obtain(IApplicationThread client, IBinder activityToken) {
        ClientTransaction instance = ObjectPool.obtain(ClientTransaction.class);
        if (instance == null) {
            instance = new ClientTransaction();
        }
        //找到了,这里的mClient是被传进来的client初始化的。而client是proc.getThread(),我们上述
        //分析得到proc.getThread()方法获得的是ApplicationThread的方法
        instance.mClient = client;
        instance.mActivityToken = activityToken;

        return instance;
    }

所以回到上面,最后调用的是ApplicationThread的scheduleTransaction方法。我们来看看该方法:

private class ApplicationThread extends IApplicationThread.Stub{
    @Override
    public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
        ActivityThread.this.scheduleTransaction(transaction);
    }
}

如上所示,最后调用的是ActivityThread的scheduleTransaction方法,来看看该方法:

    void scheduleTransaction(ClientTransaction transaction) {
        transaction.preExecute(this);
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }

如上所示,最终发送消息给ActivityThread.H,将transaction交给H的handleMessage方法进行处理:

case EXECUTE_TRANSACTION:
	final ClientTransaction transaction = (ClientTransaction) msg.obj;
	mTransactionExecutor.execute(transaction);
	if (isSystem()) {
        transaction.recycle();
    }
	break;

msg.obj就是sendMessage里的transaction,来看看mTransactionExecutor的初始化

private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);

所以最后调用的是TransactionExecutor里的execute方法,进去看看

//TransactionExecutor.java    
public void execute(ClientTransaction transaction) {

        if (token != null) {
            final Map<IBinder, ClientTransactionItem> activitiesToBeDestroyed =
                    mTransactionHandler.getActivitiesToBeDestroyed();
            final ClientTransactionItem destroyItem = activitiesToBeDestroyed.get(token);
            if (destroyItem != null) {
                if (transaction.getLifecycleStateRequest() == destroyItem) {
                    // It is going to execute the transaction that will destroy activity with the
                    // token, so the corresponding to-be-destroyed record can be removed.
                    activitiesToBeDestroyed.remove(token);
                }
                
            }
        }

        if (DEBUG_RESOLVER) Slog.d(TAG, transactionToString(transaction, mTransactionHandler));

        executeCallbacks(transaction);

        executeLifecycleState(transaction);
        mPendingActions.clear();
        if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "End resolving transaction");
    }

在executeCallbacks中

//TransactionExecutor.java        
@VisibleForTesting
    public void executeCallbacks(ClientTransaction transaction) {
        final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
        if (callbacks == null || callbacks.isEmpty()) {
            // No callbacks to execute, return early.
            return;
        }
        if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Resolving callbacks in transaction");

        final IBinder token = transaction.getActivityToken();
        ActivityClientRecord r = mTransactionHandler.getActivityClient(token);

        // In case when post-execution state of the last callback matches the final state requested
        // for the activity in this transaction, we won't do the last transition here and do it when
        // moving to final state instead (because it may contain additional parameters from server).
        final ActivityLifecycleItem finalStateRequest = transaction.getLifecycleStateRequest();
        final int finalState = finalStateRequest != null ? finalStateRequest.getTargetState()
                : UNDEFINED;
        // Index of the last callback that requests some post-execution state.
        final int lastCallbackRequestingState = lastCallbackRequestingState(transaction);

        final int size = callbacks.size();
        for (int i = 0; i < size; ++i) {
            final ClientTransactionItem item = callbacks.get(i);
            if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Resolving callback: " + item);
            final int postExecutionState = item.getPostExecutionState();
            final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r,
                    item.getPostExecutionState());
            if (closestPreExecutionState != UNDEFINED) {
                cycleToPath(r, closestPreExecutionState, transaction);
            }
			//重点是这里
            item.execute(mTransactionHandler, token, mPendingActions);
            item.postExecute(mTransactionHandler, token, mPendingActions);
            if (r == null) {
                // Launch activity request will create an activity record.
                r = mTransactionHandler.getActivityClient(token);
            }

            if (postExecutionState != UNDEFINED && r != null) {
                // Skip the very last transition and perform it by explicit state request instead.
                final boolean shouldExcludeLastTransition =
                        i == lastCallbackRequestingState && finalState == postExecutionState;
                cycleToPath(r, postExecutionState, shouldExcludeLastTransition, transaction);
            }
        }
    }

主要看item.execute,这个item是从callback中获取出来的,如下所示:

final ClientTransactionItem item = callbacks.get(i);

这个callbacks又是transaction.getCallbacks()得到,而这getCallbacks得到的值是通过addCallback添加的,在ActivityStackSupervisor的realStartActivityLocked中添加进去的,如下所示:

//ActivityStackSupervisor
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
            boolean andResume, boolean checkConfig) throws RemoteException {

				//省略
    			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.obtain得到的是一个LaunchActivityItem对象,所以item是LaunchActivityItem类型。那么我们看看LaunchActivityItem里的execute方法

//LaunchActivityItem.java    
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.handleLaunchActivity(r, pendingActions, null /* customIntent */);
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }

我们看一下execute的第一个参数client,这个方法调用如下:

//TransactionExecutor.java    
item.execute(mTransactionHandler, token, mPendingActions);

mTransactionHandler是TransactionExecutor的成员变量,而在TransactionExecutor中mTransactionHandler被初始化的地方只有它的构造函数,那么我们看看它构造函数是在哪里被调用的。追溯后发现,是在ActivityThread里被构造的:

//TransactionExecutor.java
public TransactionExecutor(ClientTransactionHandler clientTransactionHandler) {
     mTransactionHandler = clientTransactionHandler;
}

//ActivityThread.java
private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);

所以,mTransactionHandler是ActivityThread类型。所以最终调用的是ActivityThread的handleLaunchActivity方法,我们看看该方法:

    @Override
    public Activity handleLaunchActivity(ActivityClientRecord r,
            PendingTransactionActions pendingActions, Intent customIntent) {
        // If we are getting ready to gc after going to the background, well
        // we are back active so skip it.
        unscheduleGcIdler();
        mSomeActivitiesChanged = true;

        if (r.profilerInfo != null) {
            mProfiler.setProfiler(r.profilerInfo);
            mProfiler.startProfiling();
        }

        // Make sure we are running with the most recent config.
        handleConfigurationChanged(null, null);

        if (localLOGV) Slog.v(
            TAG, "Handling launch of " + r);

        // Initialize before creating the activity
        if (!ThreadedRenderer.sRendererDisabled
                && (r.activityInfo.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
            HardwareRenderer.preload();
        }
        WindowManagerGlobal.initialize();

        // Hint the GraphicsEnvironment that an activity is launching on the process.
        GraphicsEnvironment.hintActivityLaunch();
		//重点这里
        final Activity a = performLaunchActivity(r, customIntent);

        if (a != null) {
            r.createdConfig = new Configuration(mConfiguration);
            reportSizeConfigurations(r);
            if (!r.activity.mFinished && pendingActions != null) {
                pendingActions.setOldState(r.state);
                pendingActions.setRestoreInstanceState(true);
                pendingActions.setCallOnPostCreate(true);
            }
        } else {
            // If there was an error, for any reason, tell the activity manager to stop us.
            try {
                ActivityTaskManager.getService()
                        .finishActivity(r.token, Activity.RESULT_CANCELED, null,
                                Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
        }

        return a;
    }

看看performLaunchActivity方法

/**  Core implementation of activity launch. */
    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ActivityInfo aInfo = r.activityInfo;
        //省略
                //重要的是这里
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
//省略
        return activity;
    }

看看callActivityOnCreate方法

    public void callActivityOnCreate(Activity activity, Bundle icicle) {
        prePerformCreate(activity);
        activity.performCreate(icicle);
        postPerformCreate(activity);
    }

到此,通过ActivityThread的main方法启动Activity流程已经结束,我们来总结一下。

总结:

  1. 我们启动应用程序时,首先会启动的是zygote进程,然后由该进程
    启动系统服务以及其它服务等。当一个应用进程启动后,就会加载
    在AndroidManifest.xml里面设置的默认加载的Activity。此时的
    加载入口是ActivityThread里面的main方法。该方法是整个程序的
    入口。在该方法里,首先会创造一个主线程相关的消息机制,即调用
    Looper.prepareMainLooper方法,然后创建一个ActivityThread对象,
    并调用ActivityThread里的attach方法。最后调用Looper.prepare来
    开启消息循环。

  2. 在attach方法中,首先判断是否是系统应用,如果是系统应用会走
    另外一套逻辑,我们关注的是不是系统应用这一部分。在不是系统应用
    这一部分的代码逻辑中,首先会通过AIDL来获取ActivityManagerService
    的对象,然后调用ActivityManagerService里面的attachApplication.

  3. 在ActivityManagerService的attachApplication中,会调用ActivityManagerService
    下的attachApplicationLocked.

  4. attachApplicationLocked方法比较长,主要做看以下几件事:

    (1)调用ActivityThread的bindApplication方法启动Application
    (2)调用ActivityTaskManagerService的内部类LocalService的 attachApplicationLocked方法,该方法会调用RootActivityContainer的attachApplication方法,然后调用ActivityStackSupervisor的realStartActivityLocked方法去启动ActivityStack的栈顶的Activity
    (3)调用ActivityService的attachApplicationLocked方法启动当前进程的Service
    (4)检查是否有广播broadcast到这个application,如果有则广播

  5. 主要关注第2件事。最终会调用ActivityStackSupervisor的realStartActivityLocked方法,该方法会创建一个ClientTransaction对象,然后调用addCallback方法加入一个LaunchActivityItem对象(这个地方后面会用到),然后一系列的调用,最终会调用ApplicationThread的scheduleTransaction方法,该方法会调用ActivityThread的scheduleTransaction方法,在该方法中会调用sendMessage发送msg.what为EXCUTE_TRANSACTION的消息到ActivityThread的H中进行处理。在H中,会调用TransactionExecutor中的execute方法,该方法会调用executeCallbacks方法,而该方法中会调用LaunchActivityItem中的execute方法。然后该方法中会继续调用ClientTransactionHandler的handleLaunchActivity方法,该方法是ActivityThread的父类,最终调用的是ActivityThread的handleLaunchActivity方法,然后调用performLaunchActivity方法,最终会调用Instrumentation的callActivityOnCreate方法,最后会调用Activity的onCreate方法,到此Activity的启动大致结束。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值