美文网首页Android开发Android开发Android开发经验谈
Android源码探究:Activity启动流程完全解析(下)

Android源码探究:Activity启动流程完全解析(下)

作者: 丶蓝天白云梦 | 来源:发表于2019-05-07 11:45 被阅读9次

    概述

    本文的内容紧接着上一篇文章Android源码探究:Activity启动流程完全解析(上),继续介绍Activity的启动流程。

    主流程分析

    8-1、ActivityManagerService#activityPaused(token)
    经过客户端的跨进程调用,AMS的activityPaused(token)被调用了。

        @Override
        public final void activityPaused(IBinder token) {
            final long origId = Binder.clearCallingIdentity();
            synchronized(this) {
                ActivityStack stack = ActivityRecord.getStackLocked(token);
                if (stack != null) {
                    stack.activityPausedLocked(token, false);
                }
            }
            Binder.restoreCallingIdentity(origId);
        }
    

    根据token来获取Activity所在的ActivityStack,进一步调用activityPausedLocked(params..)

    8-2、ActivityStack#activityPausedLocked(params..)

    final void activityPausedLocked(IBinder token, boolean timeout) {
        //先从ActivityStack根据token取出对应的ActivityRecord
        final ActivityRecord r = isInStackLocked(token);
        if (r != null) {
            mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
            //如果二者相等,表示记录的需要暂停的Activity已经暂停完毕
            if (mPausingActivity == r) {
                mService.mWindowManager.deferSurfaceLayout();
                try {
                    completePauseLocked(true /* resumeNext */, null /* resumingActivity */);
                } finally {
                    mService.mWindowManager.continueSurfaceLayout();
                }
                return;
            } else {
                //省略...
            }
        }
        mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
    }
    

    这里没什么好说的,我们继续看completePauseLocked(params..)

    8-3、ActivityStack#completePauseLocked(params..)

    private void completePauseLocked(boolean resumeNext, ActivityRecord resuming) {
        ActivityRecord prev = mPausingActivity;
    
        //省略大部分的代码...
    
        if (resumeNext) {
            final ActivityStack topStack = mStackSupervisor.getFocusedStack();
            if (!topStack.shouldSleepOrShutDownActivities()) {
                mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null);
            } else {
                //...
            }
        }
    
    }
    

    当代码执行到这里的时候,读者应该对这个方法resumeFocusedStackTopActivityLocked(params..)有点眼熟吧?上面已经执行过该方法了,接下来的调用链都是一样的了,最终会执行到ActivityStackSupervisor#startSpecificActivityLocked(params..)这个方法,进行Activity的真正启动过程。

    8-4、ActivityStackSupervisor#startSpecificActivityLocked(params..)

    void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
        //获取Activity所对应的进程记录
        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true);
    
        getLaunchTimeTracker().setLaunchTime(r);
    
        //如果该进程已经启动了,那么直接开始启动Activity
        if (app != null && app.thread != null) {
            try {
                //若该Activity的flag不包含多进程标志位 或 不是安卓框架的组件
                if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                        || !"android".equals(r.info.packageName)) {
                    // Don't add this if it is a platform component that is marked
                    // to run in multiple processes, because this is actually
                    // part of the framework so doesn't make sense to track as a
                    // separate apk in the process.
                    // 如果它是一个标记为多进程运行的平台组件,则不要添加该项,
                    // 因为这实际上是安卓框架的一部分,因此在进程中作为单独的apk进行跟踪是没有意义的。
                    app.addPackage(r.info.packageName, r.info.applicationInfo.longVersionCode,
                            mService.mProcessStats);
                }
                //真正地启动一个Activity
                realStartActivityLocked(r, app, andResume, checkConfig);    
                return;
            } catch (RemoteException e) {
                //...
            }
    
            // If a dead object exception was thrown -- fall through to
            // restart the application.
        }
    
        //代码9-1:否则,先启动一个新的进程,然后再启动Activity
        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
    }
    

    代码的逻辑很清晰明了,主要是先判断Activity所对应的进程是否已经存在,如果存在了那就直接去执行真正的启动Activity过程;如果该进程还不存在,那么就要去启动一个进程。接下来的分析有两条路可以走,一是沿着Activity启动进行分析;二是沿着进程的启动进行分析。实际上进程的启动完毕之后也还是要进行Activity的启动的。也就是说调用了mService.startProcessLocked(params)后,会启动新的进程,然后ActivityStackSupervisor再次调用realStartActivityLocked(params..)在进程内启动Activity。
    其实,这个调用顺序符合这一种情况:在进程A的ActivityA内启动了进程B的ActivityB,此时先暂停进程A的ActivityA,然后进程B还没有启动,那么先启动进程B,然后再启动ActivityB。
    因此,接下来我们先来看怎样启动一个新的进程。


    9-1、ActivityManagerService#startProcessLocked(params..)

    final ProcessRecord startProcessLocked(String processName,
            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
            boolean isolated, boolean keepIfLarge) {
        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
                null /* crashHandler */);
    }
    
    private final boolean startProcessLocked(ProcessRecord app, String hostingType,
            String hostingNameStr, boolean disableHiddenApiChecks, String abiOverride) {
            //省略大部分代码...
    
            final String entryPoint = "android.app.ActivityThread";
            return startProcessLocked(hostingType, hostingNameStr, entryPoint, app, uid, gids,
                    runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
                    startTime);
        } 
    }
    //一系列startProcessLocked(params..)重载方法的调用
    //最终会调用下面的startProcess(params..)方法
    
    private ProcessStartResult startProcess(String hostingType, String entryPoint,
            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
            String seInfo, String requiredAbi, String instructionSet, String invokeWith,
            long startTime) {
        try {
            final ProcessStartResult startResult;
            if (hostingType.equals("webview_service")) {
                startResult = startWebView(entryPoint,
                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, null,
                        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,
                        new String[] {PROC_START_SEQ_IDENT + app.startSeq});
            }
            return startResult;
        } 
    }
    

    中间省略了大部分的重载方法的调用,最后来到了Process.start(params..),把一系列进程有关的信息都传递了进去,根据这些信息来创建一个进程。

    9-2、Process#start(params..)
    这个类的源码在Android SDK内可以找到,我们直接看它的代码:

    public static final ProcessStartResult start(final String processClass,
                                  final String niceName,
                                  int uid, int gid, int[] gids,
                                  int runtimeFlags, int mountExternal,
                                  int targetSdkVersion,
                                  String seInfo,
                                  String abi,
                                  String instructionSet,
                                  String appDataDir,
                                  String invokeWith,
                                  String[] zygoteArgs) {
        return zygoteProcess.start(processClass, niceName, uid, gid, gids,
                    runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                    abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
    }
    

    这里我们需要关注一个参数processClass,当一个进程被启动后,以processClass为类名的类的main(args)函数会被调用。而这里的processClass是代码9-1中传递进来的“android.app.ActivityThread”。那么也就是说,一个新的进程启动后,它的ActivityThread的main()函数会最先得到执行。所以,ActivityThread#main()是整个应用程序的入口

    9-3、zygoteProcess#start(params..)
    代码执行到了zygoteProcess的start(params..)方法,我们先来看一下代码的执行:

    public final Process.ProcessStartResult start(final String processClass,
            final String niceName,int uid, int gid, int[] gids,
            int runtimeFlags, int mountExternal,int targetSdkVersion,
            String seInfo,String abi,String instructionSet,String appDataDir,
            String invokeWith,String[] zygoteArgs) {
        try {
            return startViaZygote(processClass, niceName, uid, gid, gids,
                    runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                    abi, instructionSet, appDataDir, invokeWith, false /* startChildZygote */,
                    zygoteArgs);
        } catch{
            //...
        }
    }
    
    private Process.ProcessStartResult startViaZygote(params...)throws ZygoteStartFailedEx {
        ArrayList<String> argsForZygote = new ArrayList<String>();
    
        //为zygote进程添加各种参数...
        argsForZygote.add("--runtime-args");
        argsForZygote.add("--setuid=" + uid);
        argsForZygote.add("--setgid=" + gid);
        //省略...
    
        //这里加了锁,同一时间内只允许一条线程执行创建进程的操作
        synchronized(mLock) {
            return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
        }
    }
    
    /**
     * 把新进程的参数发给zygote进程,它会创建一个子进程,并返回子进程的pid
     *
     */
    @GuardedBy("mLock")
    private static Process.ProcessStartResult zygoteSendArgsAndGetResult(
            ZygoteState zygoteState, ArrayList<String> args)
            throws ZygoteStartFailedEx {
        try {
            //这里的跨进程通信,使用的是socket通信机制
            //由于这里都是在锁的机制下执行,所以不会出现并发错误  
            final BufferedWriter writer = zygoteState.writer;
            final DataInputStream inputStream = zygoteState.inputStream;
    
            //把所有新进程的参数都写入缓冲区
            writer.write(Integer.toString(args.size()));
            writer.newLine();
    
            for (int i = 0; i < sz; i++) {
                String arg = args.get(i);
                writer.write(arg);
                writer.newLine();
            }
    
            writer.flush();
    
            // Should there be a timeout on this?
            Process.ProcessStartResult result = new Process.ProcessStartResult();
    
            //读取zygote进程返回的值,这就是新进程的pid
            result.pid = inputStream.readInt();
            result.usingWrapper = inputStream.readBoolean();
    
            if (result.pid < 0) {
                throw new ZygoteStartFailedEx("fork() failed");
            }
            return result;
        } 
    }
    

    zygote到底是何方神圣呢?其实在安卓系统启动的过程中,zygote进程就会被启动,它负责了整个frameworks层和application层的所有进程的创建和启动工作。也就是说,所有的进程都是它孕育出来的,都是它的子进程。同时,zygote的中文意思受精卵刚好与它的行为相符合。
    需要注意的是,上面的代码都是运行在AMS内,只不过最后通过socket跨进程通信的方式通知了zygote进程来fork一个子进程,并且获取到了子进程的pid。该子进程创建、启动完毕之后,ActivityThread#main()方法就得到了调用。


    10-1、ActivityThread#main()
    ActivityThread的main()方法可以说是我们应用程序的开端,它运行在一个新的进程空间内。当一个新的进程启动完毕开始运行后,它首先要做的是通知AMS它被启动了,因为此时AMS还等着它去执行启动Activity的后续流程呢。我们来看看main()方法做了什么工作:

    public static void main(String[] args) {
        //初始化环境
        Environment.initForCurrentUser();
    
        // Set the reporter for event logging in libcore
        EventLogger.setReporter(new EventLoggingReporter());
    
        // Make sure TrustedCertificateStore looks in the right place for CA certificates
        final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
        TrustedCertificateStore.setDefaultUserDirectory(configDir);
    
        Process.setArgV0("<pre-initialized>");
    
        //为主线程准备Looper
        Looper.prepareMainLooper();
    
        //从命令行参数中获取序列号
        long startSeq = 0;
        if (args != null) {
            for (int i = args.length - 1; i >= 0; --i) {
                if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) {
                    startSeq = Long.parseLong(
                            args[i].substring(PROC_START_SEQ_IDENT.length()));
                }
            }
        }
        //创建ActivityThread的实例
        ActivityThread thread = new ActivityThread();
        thread.attach(false, startSeq);    //通知AMS进行绑定操作
    
        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }
    
        Looper.loop();      //开启主线程的消息循环
    
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }
    

    代码的逻辑很清晰,关键的地方上面也有注释。可以看出,在main()函数的最后,开启了主线程的消息循环,通过Handler和Looper的组合,可以不断地处理AMS、WMS发过来的消息请求等,有关主线程消息循环的内容,有兴趣的可以自行查阅相关的信息,这里不做展开讲述。我们的关注点放在thread.attach(false,startSeq)这行代码内,我们看看它做了什么工作吧。

    10-2、ActivityThread#attach(params..)

    private void attach(boolean system, long startSeq) {
        sCurrentActivityThread = this;
        mSystemThread = system;
        if (!system) {
            //获取AMS在客户端的代理对象
            final IActivityManager mgr = ActivityManager.getService();
            try {
                //进行跨进程通信,通知AMS进行绑定操作
                //这里的mAppThread就是ApplicationThread,在ActivityThread
                //被实例化的时候,它也被实例化了。
                mgr.attachApplication(mAppThread, startSeq);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
            
        } else {
            //...
        }
        //...
    }
    

    上面的代码出现了ApplicationThread对象,它在前面已经出现过很多次了,它是一个Binder对象,用于AMS来跨进程与APP进行消息通信。这里通过Binder跨进程通信,调用了AMS的attachApplication(params..)方法。我们再次打开AMS的代码,找到该方法。(需要注意的是:应用程序的主线程执行完该方法之后,继续进行消息循环,以等待下一次AMS的消息。)

    10-3、ActivityManagerService#attachApplication(params..)

    @Override
    public final void attachApplication(IApplicationThread thread, long startSeq) {
        synchronized (this) {
            //..
            attachApplicationLocked(thread, callingPid, callingUid, startSeq);
        }
    }
    
    private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid, int callingUid, long startSeq) {
        ProcessRecord app;
        long startTime = SystemClock.uptimeMillis();
        //根据pid来获取进程记录
        if (pid != MY_PID && pid >= 0) {
            synchronized (mPidsSelfLocked) {
                app = mPidsSelfLocked.get(pid);
            }
        } else {
            app = null;
        }
    
        //ProcessRecord保存了当前的IApplicationThread,即保存了客户端的一个代理对象
        //AMS能根据该Binder对象快速找到所指的应用
        app.makeActive(thread, mProcessStats);  
        
        //省略大部分代码...
    
            if (app.isolatedEntryPoint != null) {
                //...
            } else if (app.instr != null) {
                //代码11-1、跨进程调用ApplicationThread的方法,告诉APP端有关该进程的信息
                thread.bindApplication(processName, appInfo, providers,
                        app.instr.mClass,
                        profilerInfo, app.instr.mArguments,
                        app.instr.mWatcher,
                        app.instr.mUiAutomationConnection, testMode,
                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
                        isRestrictedBackupMode || !normalMode, app.persistent,
                        new Configuration(getGlobalConfiguration()), app.compat,
                        getCommonServicesLocked(app.isolated),
                        mCoreSettingsObserver.getCoreSettingsLocked(),
                        buildSerial, isAutofillCompatEnabled);
                } else {
                    //...
                }
                
            } 
    
        // See if the top visible activity is waiting to run in this process...
        if (normalMode) {
            try {
                //代码12-1、告诉ActivityStackSupervisor,该app已经完成了绑定操作,可以启动一个Activity了
                if (mStackSupervisor.attachApplicationLocked(app)) {
                    didSomething = true;
                }
            } 
        }
        return true;
    }
    

    上面已经省略了大部分的代码,很多都是异常状态的处理以及初始化等逻辑,核心在于thread.bindApplication(params..)mStackSupervisor.attachApplicationLocked(app)这两个方法的调用上。前一行代码通过IApplicationThread跨进程通信,调用了APP端的相应方法,把有关进程的重要信息传递了过去。这样便完成从客户端到服务端的绑定操作。后一行代码,通过ActivityStackSupervisor来找到对应的ActivityStack,然后进行绑定,这样便完成了从服务端到客户端的绑定操作。通过这两个操作,客户端的应用程序知道了自己的应用信息、进程信息等;而服务端则知道了客户端的Binder代理对象,方便之后的跨进程操作。


    11-1、ApplicationThread#bindApplication(params..)
    我们先来看该方法的调用,我们又从AMS进程回到了应用进程:

    public final void bindApplication(params..) {
    
        if (services != null) {
    
            // Setup the service cache in the ServiceManager
            ServiceManager.initServiceCache(services);
        }
    
        setCoreSettings(coreSettings);
    
        AppBindData data = new AppBindData();
        data.processName = processName;
        data.appInfo = appInfo;
        data.providers = providers;
        //省略赋值代码..
            
        //通过Handler发送消息
        sendMessage(H.BIND_APPLICATION, data);
    }
    

    由此可见,App的有关信息从AMS传递了过来,并保存在了AppBindData这个对象内。接着,就是我们熟悉的发送消息过程,通过Handler切换到主线程,在主线程内处理这个消息。代码如下:

    public void handleMessage(Message msg) {
        switch (msg.what) {
            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;        
        }
        Object obj = msg.obj;
        if (obj instanceof SomeArgs) {
            ((SomeArgs) obj).recycle();
        }
    }
    

    得益于主线程的消息循环,当H接受到BIND_APPLICATION的消息时,就能马上开始处理这个消息,处理完毕后继续消息循环。

    11-2、ActivityThread#handleBindApplication(data)

    private void handleBindApplication(AppBindData data) {
        //省略大部分代码...
    
        //创建上下文环境context
        final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
            
        Application app;
        try {
            app = data.info.makeApplication(data.restrictedBackupMode, null);
            
            //....
            try {
                mInstrumentation.callApplicationOnCreate(app);
            }
        }
    }
    

    以上省略了绝大部分的代码,很多都是初始化代码,比如加载各种库等。当Application初始化完毕之后,调用了mInstrumentation.callApplicationOnCreate(app)

    11-3、Instrumentation#callApplicationOnCreate(app)

    public void callApplicationOnCreate(Application app) {
            app.onCreate();
        }
    

    很简单,调用了Application#onCreate()方法,也就是我们业务层常重写的方法之一,代码执行到这里,应用程序的初始化已经完成了。下面就是在应用程序的基础上启动一个Activity了。


    12-1、ActivityStackSupervisor#attachApplicationLocked(app)
    回到10-3的代码,继续往下执行,接着AMS就会调用mStackSupervisor.attachApplicationLocked(app)方法,可想而知,在方法的内部,应该是要启动一个Activity了。因为一切的准备工作都已经完成了。

    boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
        final String processName = app.processName;
        boolean didSomething = false;
        for (...) {
            for (...) {
                for (int i = 0; i < size; i++) {
                    final ActivityRecord activity = mTmpActivityList.get(i);
    
                    //如果该ActivityRecord的进程字段为空 并且进程uid与Activity的进程id相同
                    //并且 进程名字与Activity的进程名字相同
                    if (activity.app == null && app.uid == activity.info.applicationInfo.uid
                            && processName.equals(activity.processName)) {
                        try {
                            //启动该Activity
                            if (realStartActivityLocked(activity, app,
                                    top == activity /* andResume */, true /* checkConfig */)) {
                                didSomething = true;
                            }
                        } 
                    }
                }
            }
        }
        return didSomething;
    }
    

    上面代码的逻辑主要是遍历所有的任务栈,找到活跃的任务栈后,再在其中找到需要启动的Activity,将它启动。启动的逻辑放在了realStartActivityLocked(params..),终于,我们又看到了这个方法,殊途同归。

    12-2、ActivityStackSupervisor#realStartActivityLocked(params..)

    final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, boolean checkConfig) throws RemoteException {
    
        //这里进行了判断,如果有Activity处于未暂停的状态,则不能启动一个新的Activity
        //由于我们是从客户端通知server来启动一个Activity的,因此已经不存在未暂停的Activity了
        if (!allPausedActivitiesComplete()) {   
            return false;
        }
    
        final TaskRecord task = r.getTask();
        final ActivityStack stack = task.getStack();
    
        try {
                //创建一个客户端的事务
                final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
                        r.appToken);
                //添加callback,留意这里的添加了LaunchActivityItem
                clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                        System.identityHashCode(r), r.info,
                        mergedConfiguration.getGlobalConfiguration(),
                        mergedConfiguration.getOverrideConfiguration(), r.compat,
                        r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
                        r.persistentState, results, newIntents, mService.isNextTransitionForward(),
                        profilerInfo));
    
                //为该事务的目标设置为ResumeActivityItem,即启动一个Activity,并改变它
                //的生命周期到Resumed状态
                final ActivityLifecycleItem lifecycleItem;
                if (andResume) {
                    lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
                } 
                clientTransaction.setLifecycleStateRequest(lifecycleItem);
    
                //通过事务管理器执行一个事务
                mService.getLifecycleManager().scheduleTransaction(clientTransaction);
            } 
        return true;
    }
    

    可以看到,我们再次遇到了熟悉的ClientTransaction,前面解析暂停Activity时也遇到它,那么接下来的逻辑应该就是与暂停的逻辑差不多了,只不过现在的ActivityLifecycleItem变成了ResumeActivityItem,即Activity的目标状态是resumed。接下来的调用链与前面见过的是一致的,即:ClientLifecycleManager#scheduleTransaction(clientTransaction)
    ——>ClientTransaction.schedule()
    ——>IApplicationThread.scheduleTransaction(this)
    ——>ActivityThread#scheduleTransaction(transaction)
    ——>H#handleMessage(msg)
    ——>TransactionExecutor#execute(transaction)
    其中,通过IApplicationThread这个Binder对象进行了跨进程调用,调用了APP端的方法,此时从AMS进程切换到了我们的应用进程。紧接着,通过Handler机制切换到了主线程,并在主线程处理EXECUTE_TRANSACTION这个消息,接着进一步交给TransactionExecutor来处理这个事务。


    13-1、TransactionExecutor#execute(transaction)
    在代码7-1已经介绍过这个方法了,我们再来简单看一下就行:

        public void execute(ClientTransaction transaction) {
            final IBinder token = transaction.getActivityToken();
            log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);
    
            executeCallbacks(transaction);
    
            executeLifecycleState(transaction);
            mPendingActions.clear();
            log("End resolving transaction");
        }
    

    在代码12-2中,我们有留意到初始化clientTransaction时,为它添加了一个callback,即LaunchActivityItem,那么这里首先会执行executeCallbacks(transaction)方法。

    13-2、TransactionExecutor#executeCallbacks(transaction)

    public void executeCallbacks(ClientTransaction transaction) {
        final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
        if (callbacks == null) {
            // No callbacks to execute, return early.
            return;
        }
        log("Resolving callbacks");
    
        final IBinder token = transaction.getActivityToken();
        ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
    
        //根据前面的代码,这里的size为1
        final int size = callbacks.size();
        for (int i = 0; i < size; ++i) {
            final ClientTransactionItem item = callbacks.get(i);
            log("Resolving callback: " + item);
    
            //这里的Item实际上就是LaunchActivityItem.
            item.execute(mTransactionHandler, token, mPendingActions);
            item.postExecute(mTransactionHandler, token, mPendingActions);
    
            //...
        }
    }
    

    在方法内部调用了LaunchActivityItem的相关方法,其中关键是LaunchActivityItem#execute(params..)

    13-3、LaunchActivityItem#execute(params..)

    public void execute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
        //实例化一个ActivityClientRecord
        ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
                mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
                mPendingResults, mPendingNewIntents, mIsForward,
                mProfilerInfo, client);
        //实际上调用的是ActivityThread的handleLaunchActivity方法
        client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }
    

    这里的ClientTransactionHandlerActivityThread的父类,而ActivityThread重写了该方法,因此我们到ActivityThread寻找该方法。

    13-4、ActivityThread#handleLaunchActivity(params..)

    public Activity handleLaunchActivity(ActivityClientRecord r,
            PendingTransactionActions pendingActions, Intent customIntent) {
        //....
    
        final Activity a = performLaunchActivity(r, customIntent);
    
        //...
    
        return a;
    }
    
    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        
        //省略部分代码..
    
        ActivityInfo aInfo = r.activityInfo;
        ContextImpl appContext = createBaseContextForActivity(r);   //创建Context
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);    //创建一个新的Activity
            StrictMode.incrementExpectedActivityCount(activity.getClass());
            r.intent.setExtrasClassLoader(cl);
            r.intent.prepareToEnterProcess();
            if (r.state != null) {
                r.state.setClassLoader(cl);
            }
        } 
    
        try {
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);
    
            if (activity != null) {
                appContext.setOuterContext(activity);
                //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);
    
                
                if (r.isPersistable()) {
                    //前面创建了Activity,接下来触发它的生命周期方法
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
    
                r.activity = activity;
            }
            r.setState(ON_CREATE);  //设置Activity此时的状态为onCreate
    
            mActivities.put(r.token, r);
    
        return activity;
    }
    

    经过一系列的创建、初始化过程,终于到了Instrumentation#callActivityOnCreate(params..),显然,这里就是触发Activity生命周期方法的地方了。

    13-5、Instrumentation#callActivityOnCreate(params..)

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

    没什么好说的,下一步就是Activity#performCreate(bundle)

    final void performCreate(Bundle icicle) {
        performCreate(icicle, null);
    }
    
    final void performCreate(Bundle icicle, PersistableBundle persistentState) {
        mCanEnterPictureInPicture = true;
        restoreHasCurrentPermissionRequest(icicle);
        if (persistentState != null) {
            onCreate(icicle, persistentState);  
        } else {
            onCreate(icicle);   //onCreate()生命周期方法调用
        }
        writeEventLog(LOG_AM_ON_CREATE_CALLED, "performCreate");
        mActivityTransitionState.readState(icicle);
    
        mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(
                com.android.internal.R.styleable.Window_windowNoDisplay, false);
        mFragments.dispatchActivityCreated();   //告诉Fragment分发create事件
        mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
    }
    

    最后,终于来到了Activity#onCreate()方法,也这就是我们应用Activity默认重写的一个方法。到了这一步,一个Activity终于真正地创建、启动成功了。但还没有完成,因为我们的目标状态是resumed,所以我们还要把Activity的状态逐步切换到onResume状态。
    让我们回到代码13-1的executeLifecycleState(transaction),这个方法读者应该也是熟悉的了,因为在处理pause状态时也曾经遇到过了。那么接下来的逻辑就显而易见了,具体的逻辑就在代码7-2处,只不过现在的状态路径变成了:onStart和onResume,也就是会分别调用ActivityThread#handleStartActivityActivityThread#handleResumeActivity;接着进一步调用到Activity#performStart()Activity#performResume()。最后,我们熟悉的生命周期方法onStart()onResume()都会得到调用。

    本文到这里就告一段落了,整篇文章很长,为耐心看到这里的你点赞~希望这篇文章能对您有所裨益,谢谢阅读!

    相关文章

      网友评论

        本文标题:Android源码探究:Activity启动流程完全解析(下)

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