Android10 launcher启动流程

1、Android10 源码编译相关问题

2、Android10 系统进程Zygote启动

3、Android10 系统进程SystemServer

4、Android10 launcher启动流程

5、Android10 系统发送开机广播时机

6、Android10 AppComponentFactory源码梳理

7、Android10 InputManagerService事件输入输出

8、Android10 InputManagerService本地实现

9、Android10 SystemUI系统手势导航


        上一篇说到系统进程SystemServer启动,在SystemServer中会去启动各种系统服务,这里的launcher也是启动的其中一个服务ActivityManagerService去启动的。在android10之前,系统四大组件的启动都是在ActivityManagerService中,在android10中,单独抽出了一个ActivityTaskManagerService,主要负责Activity的管理和调度。这里先来看下ActivityManagerService服务的启动:

private void startBootstrapServices() {
    ... ...
    // Activity manager runs the show.
    traceBeginAndSlog("StartActivityManager");
    // TODO: Might need to move after migration to WM.
    ActivityTaskManagerService atm = mSystemServiceManager.startService(
            ActivityTaskManagerService.Lifecycle.class).getService();
    mActivityManagerService = ActivityManagerService.Lifecycle.startService(
            mSystemServiceManager, atm);
    mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
    mActivityManagerService.setInstaller(installer);
    mWindowManagerGlobalLock = atm.getGlobalLock();
    traceEnd();
    ... ...
}

在上一篇Android10 系统进程SystemServer中有讲到SystemServiceManager,当调用它的startService()时,就会通过反射去创建传进去的class,然后在调用创建对象的onStart()方法,这里就是去初始化ActivityTaskManagerService和ActivityManagerService对象,并不会去启动launcher,上一篇有看到系统服务启动分为三块:

startBootstrapServices();   // 启动引导服务
startCoreServices();        // 启动核心服务
startOtherServices();       // 启动其他服务

在startOtherServices()最后:

private void startOtherServices() {
    ... ...
    // We now tell the activity manager it is okay to run third party
    // code.  It will call back into us once it has gotten to the state
    // where third party code can really run (but before it has actually
    // started launching the initial applications), for us to complete our
    // initialization.
    mActivityManagerService.systemReady(() -> {
        ... ...
    });
}

这就说明在所有服务初始化完成后,在这里会通知ActivityManagerService的systemReady(),launcher的启动流程就是从这里开始的:

public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
    ... ...
    mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
    ... ...
}

这里mAtmInternal类型是ActivityTaskManagerInternal,这是一个抽象类,其实现是ActivityTaskManagerService的内部类LocalService:

final class LocalService extends ActivityTaskManagerInternal {
    @Override
    public boolean startHomeOnAllDisplays(int userId, String reason) {
        synchronized (mGlobalLock) {
            return mRootActivityContainer.startHomeOnAllDisplays(userId, reason);
        }
    }

        @Override
    public void resumeTopActivities(boolean scheduleIdle){
        synchronized (mGlobalLock){
            mRootActivityContainer.resumeFocusedStacksTopActivities();
            if(scheduleIdle){
                mStackSupervisor.scheduleIdleLocked();
            }
        }
    }
}

这里的mRootActivityContainer类型是RootActivityContainer,按照文档上的说明,这是一个临时类,主要是将ActivityStackSupervisor.java中的一部分逻辑分离出来,在android11中,这个类就已经找不到了。替换成了RootWindowContainer,这里先来看下RootActivityContainer.startHomeOnAllDisplays():

boolean startHomeOnDisplay(int userId,String reason,int displayId,boolean allowInstrumenting,boolean fromHomeKey){
    // Fallback to top focused display if the displayId is invalid.
    if(displayId==INVALID_DISPLAY){
        displayId=getTopDisplayFocusedStack().mDisplayId;
    }

    Intent homeIntent=null;
    ActivityInfo aInfo=null;
    if(displayId==DEFAULT_DISPLAY){
        //拿到需要启动launcher的intent,通过resolveHomeActivity解析出需要启动的Activity
        homeIntent=mService.getHomeIntent();
        aInfo=resolveHomeActivity(userId,homeIntent);
    }else if(shouldPlaceSecondaryHomeOnDisplay(displayId)){
        Pair<ActivityInfo, Intent> info=resolveSecondaryHomeActivity(userId,displayId);
        aInfo=info.first;
        homeIntent=info.second;
    }
    if(aInfo==null||homeIntent==null){
        return false;
    }

    if(!canStartHomeOnDisplay(aInfo,displayId,allowInstrumenting)){
        return false;
    }

    // Updates the home component of the intent.
    homeIntent.setComponent(new ComponentName(aInfo.applicationInfo.packageName,aInfo.name));
    homeIntent.setFlags(homeIntent.getFlags()|FLAG_ACTIVITY_NEW_TASK);
    // Updates the extra information of the intent.
    if(fromHomeKey){
        homeIntent.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY,true);
    }
    // Update the reason for ANR debugging to verify if the user activity is the one that
    // actually launched.
    final String myReason=reason+":"+userId+":"+UserHandle.getUserId(
    aInfo.applicationInfo.uid)+":"+displayId;
    mService.getActivityStartController().startHomeActivity(homeIntent,aInfo,myReason,
    displayId);
    return true;
}

这里可以分为两步看:

        1、通过ActivityTaskManagerService的getHomeIntent()获取到需要启动的intent,在通过resolveHomeActivity()解析出需要启动Activity的信息,

        2、mService.getActivityStartController()获取到的是ActivityStartController,这个类的主要作用是用于控制委派启动的Activity。

先来看下ActivityTaskManagerService的getHomeIntent();

    Intent getHomeIntent() {
        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
        intent.setComponent(mTopComponent);
        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
            intent.addCategory(Intent.CATEGORY_HOME);
        }
        return intent;
    }

注意看intent.addCategory(Intent.CATEGORY_HOME),这个代表的就是要启动Activity的意图,通常来说,整个系统的只会有一个应用会在清单文件中配置CATEGORY_HOME,如果配置了多个,系统在启动的时候就会要求用户手动去选择哪个作为启动应用,如果在系统设置应用中进行配置了,就会选择配置的那个应用启动。

回到主线,接着看ActivityStartController.startHomeActivity():

    void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason, int displayId) {
        final ActivityOptions options = ActivityOptions.makeBasic();
        options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN);
        if (!ActivityRecord.isResolverActivity(aInfo.name)) {
            // The resolver activity shouldn't be put in home stack because when the foreground is
            // standard type activity, the resolver activity should be put on the top of current
            // foreground instead of bring home stack to front.
            options.setLaunchActivityType(ACTIVITY_TYPE_HOME);
        }
        options.setLaunchDisplayId(displayId);
        mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason)
                .setOutActivity(tmpOutRecord)
                .setCallingUid(0)
                .setActivityInfo(aInfo)
                .setActivityOptions(options.toBundle())
                .execute();
        mLastHomeActivityStartRecord = tmpOutRecord[0];
        final ActivityDisplay display =
                mService.mRootActivityContainer.getActivityDisplay(displayId);
        final ActivityStack homeStack = display != null ? display.getHomeStack() : null;
        if (homeStack != null && homeStack.mInResumeTopActivity) {
            // If we are in resume section already, home activity will be initialized, but not
            // resumed (to avoid recursive resume) and will stay that way until something pokes it
            // again. We need to schedule another resume.
            mSupervisor.scheduleResumeTopActivities();
        }
    }

    ActivityStarter obtainStarter(Intent intent, String reason) {
        return mFactory.obtain().setIntent(intent).setReason(reason);
    }

这里主要是先获取一个ActivityStarter(主要用于启动Activity),然后把需要的参数设置进去,最后再调用它的ActivityStarter.execute()方法:

    int execute() {
        try {
            // TODO(b/64750076): Look into passing request directly to these methods to allow
            // for transactional diffs and preprocessing.
            if (mRequest.mayWait) {
                return startActivityMayWait();
            } else {
                return startActivity();
            }
        } finally {
            onExecutionComplete();
        }
    }

可以看到这个方法中是加了// TODO的,意味着这个方法只是暂时的,在android11中,这个方法的实现就变了,这不影响目前流程的分析,在上面ActivityStart设置参数的时候,可以注意到并没有调用到它的setMayWait()方法,所以这里会执行startActivity(),这里在往下走,最终会调用到RootActivityContainer.resumeFocusedStacksTopActivities():

    boolean resumeFocusedStacksTopActivities(
            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
    ... ... 
    if (!resumedOnDisplay) {
        // In cases when there are no valid activities (e.g. device just booted or launcher
        // crashed) it's possible that nothing was resumed on a display. Requesting resume
        // of top activity in focused stack explicitly will make sure that at least home
        // activity is started and resumed, and no recursion occurs.
        final ActivityStack focusedStack = display.getFocusedStack();
        if (focusedStack != null) {
            //在这个方法中会调用到ActivityStackSupervisor.startSpecificActivityLocked()
            focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        }
    }
    ... ...
        return result;
    }

从注释中可以看到,当booted或是launcher crashed时没有可显示的,这时候就会就会将launcher显示出来,接着又调用了ActivityStack.resumeTopActivityUncheckedLocked():

    private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
        ... ...
        // Find the next top-most activity to resume in this stack that is not finishing and is
        // focusable. If it is not focusable, we will fall into the case below to resume the
        // top activity in the next focusable task.
        ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
        ... ...
        //进程是否已经创建了,这里是还没创建,会执行else
        if (next.attachedToProcess()) {
            ... ...
        } else {
            ... ...
            mStackSupervisor.startSpecificActivityLocked(next, true, true);
        }
        return true;
    }

进程还没有创建,执行else中语句ActivityStackSupervisor.startSpecificActivityLocked():

    void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
        ... ...
        try {
            if (Trace.isTagEnabled(TRACE_TAG_ACTIVITY_MANAGER)) {
                Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "dispatchingStartProcess:"
                        + r.processName);
            }
            // 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);
        } finally {
            Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
        }
    }

这里的mService是ActivityManagerService,通过handler发消息执行ActivityManagerInternal.startProcess(),内部又转调用ActivityManagerService.startProcessLocked():

    final ProcessRecord startProcessLocked(String processName,
            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
            HostingRecord hostingRecord, boolean allowWhileBooting,
            boolean isolated, boolean keepIfLarge) {
        return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
                hostingRecord, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
                null /* crashHandler */);
    }

mProcessList类型是ProcessList,这是一个进程管理类,描述了进程的adj值,当系统资源吃紧时,就会根据这里描述的adj去判断杀死哪个应用来释放资源,可以通过adb shell dumpsys meminfo来查看当前所有进程的分类情况,接着来看下ProcessList.startProcessLocked():

final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
            boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,
            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
        
        ProcessRecord app;
        ... ...
        checkSlow(startTime, "startProcess: stepping in to startProcess");
        final boolean success = startProcessLocked(app, hostingRecord, abiOverride);
        checkSlow(startTime, "startProcess: done starting proc!");
        return success ? app : null;
    }

    boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
            boolean disableHiddenApiChecks, boolean mountExtStorageFull,
            String abiOverride) {
            ... ...
        try {
            ... ...
            // Start the process.  It will either succeed and return a result containing
            // the PID of the new process, or else throw a RuntimeException.
            final String entryPoint = "android.app.ActivityThread";

            return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,
                    runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
                    startTime);
        } catch (RuntimeException e) {
            Slog.e(ActivityManagerService.TAG, "Failure starting process " + app.processName, e);

            // Something went very wrong while trying to start this process; one
            // common case is when the package is frozen due to an active
            // upgrade. To recover, clean up any active bookkeeping related to
            // starting this process. (We already invoked this method once when
            // the package was initially frozen through KILL_APPLICATION_MSG, so
            // it doesn't hurt to use it again.)
            mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
                    false, false, true, false, false, app.userId, "start failure");
            return false;
        }
    }

    boolean startProcessLocked(HostingRecord hostingRecord,String entryPoint,
            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
            String seInfo, String requiredAbi, String instructionSet, String invokeWith,long startTime) {
            ... ...
            final Process.ProcessStartResult startResult = startProcess(app.hostingRecord,entryPoint, app, app.startUid, gids, runtimeFlags, mountExternal,app.seInfo, requiredAbi, instructionSet, invokeWith, app.startTime);
            ... ...
    }

    private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
            String seInfo, String requiredAbi, String instructionSet, String invokeWith,
            long startTime) {
        try {
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
                    app.processName);
            checkSlow(startTime, "startProcess: asking zygote to start proc");
            final Process.ProcessStartResult startResult;
            if (hostingRecord.usesWebviewZygote()) {
                ... ...
            } 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 {
                ... ...
            }
            checkSlow(startTime, "startProcess: returned from zygote!");
            return startResult;
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        }
    }

这里有几个我们需要关注的点,一个是第二个方法定义的entryPoint="android.app.ActivityThread",这个就是后面创建进程时会通过反射调用到的类,再来看最后一个方法,这里会执行else if语句,也就是执行ZygoteProcess的start()方法,最后会通过ZygoteProcess.attemptConnectionToPrimaryZygote()去连接在Zygote进程中创建的socket,参考Android10 系统进程Zygote启动,里面有提到一个runSelectLoop()函数,那是一个无限循环函数,当没有应用创建时,它处于等待状态,当调用了ZygoteProcess.attemptConnectionToPrimaryZygote()函数,内部会调用LocalSocket.connect(),就会执行到ZygoteServer.runSelectLoop()函数中去创建进程,最后会执行ActivityThread.main():

    public static void main(String[] args) {
        ... ...

        Looper.prepareMainLooper();

        ... ...
        ActivityThread thread = new ActivityThread();
        thread.attach(false, startSeq);

        ... ...
        Looper.loop();

        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

这里就是android层面划分为一个应用进程的开始,初始化一个looper,也就是android中说的主线程,并开始looper循环,这里调用到了ActivitThread.attach():

    private void attach(boolean system, long startSeq) {
        sCurrentActivityThread = this;
        mSystemThread = system;
        if (!system) {
            ... ...
            // 这里会拿到ActivityManagerService的代理
            final IActivityManager mgr = ActivityManager.getService();
            try {
                mgr.attachApplication(mAppThread, startSeq);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
             ... ...
        } else {
            // 在前面讲Zygote进程的时候,里面创建ActivityThread就会执行到这里
        }

        //当系统配置发生变更时会执行这个回调
        ViewRootImpl.ConfigChangedCallback configChangedCallback
                = (Configuration globalConfig) -> {
            ... ...
        };
        ViewRootImpl.addConfigCallback(configChangedCallback);
    }

这里会执行if语句里面的内容,mAppThread的类型是ApplicationThread,这个类的主要作用是在ActivityManagerService中回调回ActivityThread中来,mgr是ActivityManagerService的代理,在执行它的ActivityManagerService.attachApplication()方法:

    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);
        }
    }

    private final boolean attachApplicationLocked(IApplicationThread thread,int pid, int callingUid, long startSeq) {
        ... ...
        //这里会去调用ActivityThrea的bindApplication(),也就是会去创建Application
        thread.bindApplication(... ...)
        ... ...
        // See if the top visible activity is waiting to run in this process...
        if (normalMode) {
            try {
                //调用ActivityTaskManagerService的attachApplication(),最终层层调用到ActivityStackSupervisor.java的 realStartActivityLocked()
                didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                badApp = true;
            }
        }
        ... ...
    }

这里通过ATM最终会调用到ActivityStackSupervisor.realStartActivityLocked():

boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
            boolean andResume, boolean checkConfig) throws RemoteException {
        //确保所有的Activity执行了onPause才会往下继续执行
        if (!mRootActivityContainer.allPausedActivitiesComplete()) {
            // While there are activities pausing we skipping starting any new activities until
            // pauses are complete. NOTE: that we also do this for activities that are starting in
            // the paused state because they will first be resumed then paused on the client side.
            if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE,
                    "realStartActivityLocked: Skipping start of r=" + r
                    + " some activities pausing...");
            return false;
        }
        ... ...

        try {
            ... ...
            try{
                ... ...
                if (r.isActivityTypeHome()) {
                    // 如果是home/launcher类型的activity,就去启动
                    updateHomeProcess(task.mActivities.get(0).app);
                }
                ... ...
                // Create activity launch transaction.
                final ClientTransaction clientTransaction = ClientTransaction.obtain(
                        proc.getThread(), r.appToken);

                final DisplayContent dc = r.getDisplay().mDisplayContent;
                //在回调序列的末尾添加一条消息
                clientTransaction.addCallback(LaunchActivityItem.obtain(... ...));

                // Set desired final state.
                final ActivityLifecycleItem lifecycleItem;
                if (andResume) {
                    lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
                } else {
                    lifecycleItem = PauseActivityItem.obtain();
                }
                //添加最后执行的生命周期状态
                clientTransaction.setLifecycleStateRequest(lifecycleItem);

                // 这里其实就是执行ClientTransaction的schedule()方法
                mService.getLifecycleManager().scheduleTransaction(clientTransaction);
                ... ...
            } catch (RemoteException e) {
                if (r.launchFailed) {
                    // 第二次启动失败,finish activity并放弃启动
                    Slog.e(TAG, "Second failure launching "
                            + r.intent.getComponent().flattenToShortString() + ", giving up", e);
                    proc.appDied();
                    stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
                            "2nd-crash", false);
                    return false;
                }

                //第一次启动失败,尝试重启进程
                r.launchFailed = true;
                proc.removeActivity(r);
                throw e;
            }
        } finally {
            endDeferResume();
        }
        ... ...

        return true;
    }

这里的关键点是ClientTransaction这个类,关于这个类的说明有两点:

1、一种容器,用于保存可发送给客户端的消息序列;

2、包括一个回调列表和一个最终生命周期状态;

这里的消息有五种,分别是:LaunchActivityItem、ResumeActivityItem、PauseActivityItem、StopActivityItem、DestroyActivityItem

上述代码主要就是添加LaunchActivityItem到回调列表中以及设置了最终生命周期状态ResumeActivityItem,最后在调用了ClientTransition.schedule():

public class ClientTransaction implements Parcelable, ObjectPoolItem {
    //回调列表
    @UnsupportedAppUsage
    private List<ClientTransactionItem> mActivityCallbacks;

    //最终生命周期状态
    private ActivityLifecycleItem mLifecycleStateRequest;

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

  这里的mClient类型是IApplicationThread,是从ActivityThread中传过来的ApplicationThread代理,接着就执行会ActivityThread.ApplicationThread.scheduleTransaction()——>ActivityThread.scheduleTransaction(),ActivityThread的这个方法是继承父类ClientTransactionHandler:

    /** Prepare and schedule transaction for execution. */
    void scheduleTransaction(ClientTransaction transaction) {
        transaction.preExecute(this);
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }

就是发了一个消息给ActivityThread:

    case EXECUTE_TRANSACTION:
        final ClientTransaction transaction = (ClientTransaction) msg.obj;
        mTransactionExecutor.execute(transaction);
        ... ...
        break;

接着就把传过来的消息转交给TransactionExecutor去执行了,这个类的功能就是以正确顺序管理事务执行,也就是前面添加的消息在这个类里面会按一定的顺序去执行:

    public void execute(ClientTransaction transaction) {
        ... ...
        executeCallbacks(transaction);

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

    public void executeCallbacks(ClientTransaction transaction) {
        final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
        ... ...
        final int size = callbacks.size();
        for (int i = 0; i < size; ++i) {
            final ClientTransactionItem item = callbacks.get(i);
            ... ...

            item.execute(mTransactionHandler, token, mPendingActions);
            item.postExecute(mTransactionHandler, token, mPendingActions);
            ... ...
        }
    }

    private void executeLifecycleState(ClientTransaction transaction) {
        final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
        ... ...
        lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
        lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
    }

可以看到,最后执行都是添加消息的execute()和postExecute()方法,前面添加的消息是LaunchActivityItem和ResumeActivityItem,那就来看下这两个类的execute()方法了:

LaunchActivityItem:
    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);
    }

ResumeActivityItem:
    public void execute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
        client.handleResumeActivity(token, true /* finalStateRequest */, mIsForward,
                "RESUME_ACTIVITY");
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }

最终执行的是ActivityThread的handleLaunchActivity()和handleResumeActivity(),在这两个方法中就会去执行Activity的onCreate()和onResume()方法,至此,launcher的页面就启动起来了。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值