美文网首页Android进阶之路Android开发程序员
Activity的启动过程详解(基于10.0源码)

Activity的启动过程详解(基于10.0源码)

作者: 胡飞洋 | 来源:发表于2020-07-08 23:37 被阅读0次

    概述

    话说Android中有四大组件:Activity、Service、BroadcastReceiver、ContentProvider。我们最常接触也是用户直接感受到的就是Activity了,今天来就说说Android启动的执行过程和工作原理。

    Activity是一种 展示型组件,用于展示给用户一个可以交互的页面。Activity是Android中最重要的组件,对用户来说,所有的Activity就是一个App的全部,而其他组件用户是不能直接感知的。在开发层面,要启动一个Activity可以使用Intent,分显式和隐式,并且还可以设置Activity的启动模式

    Android系统对四大组件都做了很大程度的封装,这样我们可以快速使用组件。Activity的启动在系统封装后,变的极为简单,显示启动activity代码如下:

    Intent intent = new Intent(this, TestActivity.class);
    this.startActivity(intent);
    

    这样就可以启动TestActivity了,那么问题来了,

    • 这个代码是如何启动一个Activity的?
    • 里面做了哪些事情?
    • onCreate这些生命周期是何时执行的?
    • Activity对象何时创建的?
    • 视图是怎么处理以及何时可见的?

    那么为啥需要了解这些问题呢?不了解 ,平时开发好像也没啥问题啊。其实不然,解决这些问题后,你会对Android系统有更深层次的理解,也会学习到系统源码优秀的设计。并且对解决一些高级问题和深入的性能优化问题有很大帮助,是技术进阶的必要阶段。这就需要我们通过阅读源码来梳理这些问题,但另一方面,系统源码是很庞大繁杂的,我们需要带着问题抓住主流程,不能陷入代码细节——这是阅读系统源码以及其他第三方库源码的正确姿势。

    流程分析

    Activity启动的发起

    下面我们就来对Activity的工作流程进行梳理,达到对Activity整体流程的掌握。从startActivity方法开始,会走到startActivityForResult方法:

        public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
                @Nullable Bundle options) {
            if (mParent == null) {
                options = transferSpringboardActivityOptions(options);
                Instrumentation.ActivityResult ar =
                    mInstrumentation.execStartActivity(
                        this, mMainThread.getApplicationThread(), mToken, this,
                        intent, requestCode, options);
                if (ar != null) {
                    mMainThread.sendActivityResult(
                        mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                        ar.getResultData());
                }
                if (requestCode >= 0) {
                    mStartedActivity = true;
                }
    
                cancelInputsAndStartExitTransition(options);
            } else {
                ...
            }
        }
    

    看到里面调用了mInstrumentation.execStartActivity方法,其中一个参数mMainThread.getApplicationThread(),它的类型是ApplicationThread,ApplicationThread是ActivityThread的内部类,继承IApplicationThread.Stub,也是个Binder对象,在Activity工作流程中有重要作用。而Instrumentation具有跟踪application及activity生命周期的功能,用于android 应用测试框架中代码检测。接着看下mInstrumentation.execStartActivity方法:

        public ActivityResult execStartActivity(
                Context who, IBinder contextThread, IBinder token, Activity target,
                Intent intent, int requestCode, Bundle options) {
            IApplicationThread whoThread = (IApplicationThread) contextThread;
            Uri referrer = target != null ? target.onProvideReferrer() : null;
            if (referrer != null) {
                intent.putExtra(Intent.EXTRA_REFERRER, referrer);
            }
            ...
            
            try {
                intent.migrateExtraStreamToClipData();
                intent.prepareToLeaveProcess(who);
                int result = ActivityManager.getService()
                    .startActivity(whoThread, who.getBasePackageName(), intent,
                            intent.resolveTypeIfNeeded(who.getContentResolver()),
                            token, target != null ? target.mEmbeddedID : null,
                            requestCode, 0, null, options);
                checkStartActivityResult(result, intent);
            } catch (RemoteException e) {
                throw new RuntimeException("Failure from system", e);
            }
            return null;
        }
    

    这里看到Activity的启动又交给了ActivityManager.getService(),这是啥?跟进去看看:

        public static IActivityManager getService() {
            return IActivityManagerSingleton.get();
        }
        private static final Singleton<IActivityManager> IActivityManagerSingleton =
                new Singleton<IActivityManager>() {
                    @Override
                    protected IActivityManager create() {
                        final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                        final IActivityManager am = IActivityManager.Stub.asInterface(b);
                        return am;
                    }
                };
    

    看到这里你应该明白了:这里是获取一个跨进程的服务。然后我们看下著名的ActivityManagerService类

    public class ActivityManagerService extends IActivityManager.Stub
            implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback
    

    ActivityManagerService继承IActivityManager.Stub,实际也就是继承了Binder并且实现了IActivityManager这个Binder接口,AMS也就是一个Binder,是IActivityManager的集体实现。所以ActivityManager.getService()获取的Binder对象,具体实现是ActivityManagerService(AMS),并且是通过单例提供服务的。

    然后ActivityManager.getService().startActivity有个返回值result,且调用了checkStartActivityResult(result, intent):

        public static void checkStartActivityResult(int res, Object intent) {
            if (!ActivityManager.isStartResultFatalError(res)) {
                return;
            }
    
            switch (res) {
                case ActivityManager.START_INTENT_NOT_RESOLVED:
                case ActivityManager.START_CLASS_NOT_FOUND:
                    if (intent instanceof Intent && ((Intent)intent).getComponent() != null)
                        throw new ActivityNotFoundException(
                                "Unable to find explicit activity class "
                                + ((Intent)intent).getComponent().toShortString()
                                + "; have you declared this activity in your AndroidManifest.xml?");
                    throw new ActivityNotFoundException(
                            "No Activity found to handle " + intent);
                case ActivityManager.START_PERMISSION_DENIED:
                    throw new SecurityException("Not allowed to start activity "
                            + intent);
                ...
                
                case ActivityManager.START_CANCELED:
                    throw new AndroidRuntimeException("Activity could not be started for "
                            + intent);
                default:
                    throw new AndroidRuntimeException("Unknown error code "
                            + res + " when starting " + intent);
            }
        }
    

    这是用来检查Activity启动的结果,如果发生致命错误,就会抛出对应的异常。看到第一个case中就抛出了 have you declared this activity in your AndroidManifest.xml?——如果Activity没在Manifest中注册就会有这个错误。

    Activity的管理——AMS

    好了,到这里,Activity的启动就转移到系统进程提供的服务AMS中了,接着看AMS的startActivity:

        @Override
        public int startActivity(IApplicationThread caller, String callingPackage,
                Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
                int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
            return mActivityTaskManager.startActivity(caller, callingPackage, intent, resolvedType,
                    resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions);
        }
    

    AMS把启动转移到了ActivityTaskManagerService(ATMS)中了,ATMS用于管理Activity及其容器(任务、堆栈、显示等)的系统服务。接着看:

    //ActivityTaskManagerService
        @Override
        public final int startActivity(IApplicationThread caller, String callingPackage,
                Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
                int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
            return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                    resultWho, requestCode, startFlags, profilerInfo, bOptions,
                    UserHandle.getCallingUserId());
        }
        
        @Override
        public int startActivityAsUser(IApplicationThread caller, String callingPackage,
                Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
                int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
            return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                    resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
                    true /*validateIncomingUser*/);
        }
    
        int startActivityAsUser(IApplicationThread caller, String callingPackage,
                Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
                int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
                boolean validateIncomingUser) {
            enforceNotIsolatedCaller("startActivityAsUser");
    
            userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
                    Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
    
            // TODO: Switch to user app stacks here.
            return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
                    .setCaller(caller)
                    .setCallingPackage(callingPackage)
                    .setResolvedType(resolvedType)
                    .setResultTo(resultTo)
                    .setResultWho(resultWho)
                    .setRequestCode(requestCode)
                    .setStartFlags(startFlags)
                    .setProfilerInfo(profilerInfo)
                    .setActivityOptions(bOptions)
                    .setMayWait(userId)
                    .execute();
    
        }
    

    跟到startActivityAsUser中,通过getActivityStartController().obtainStarter方法获取ActivityStarter实例 然后调用一系列方法,最后的execute()方法是开始启动activity:

        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(mRequest.caller, mRequest.callingUid,
                            mRequest.callingPackage, mRequest.realCallingPid, mRequest.realCallingUid,
                            mRequest.intent, mRequest.resolvedType,
                            mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
                            mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
                            mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
                            mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
                            mRequest.inTask, mRequest.reason,
                            mRequest.allowPendingRemoteAnimationRegistryLookup,
                            mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
                } else {
                    return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
                            mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
                            mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
                            mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
                            mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
                            mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
                            mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
                            mRequest.outActivity, mRequest.inTask, mRequest.reason,
                            mRequest.allowPendingRemoteAnimationRegistryLookup,
                            mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
                }
            } finally {
                onExecutionComplete();
            }
        }
    

    分了两种情况,不过 不论startActivityMayWait还是startActivity最终都是走到下面这个startActivity方法:

        private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
                    IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                    int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
                    ActivityRecord[] outActivity, boolean restrictedBgActivity) {
            int result = START_CANCELED;
            final ActivityStack startedActivityStack;
            try {
                mService.mWindowManager.deferSurfaceLayout();
                result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                        startFlags, doResume, options, inTask, outActivity, restrictedBgActivity);
            } finally {
                final ActivityStack currentStack = r.getActivityStack();
                startedActivityStack = currentStack != null ? currentStack : mTargetStack;
    
               ...
            }
    
            postStartActivityProcessing(r, result, startedActivityStack);
            return result;
        }
    

    里面有调用了startActivityUnchecked方法,startActivityUnchecked内部调用了ActivityStack的startActivityLocked方法,startActivityLocked内部调用ensureActivitiesVisibleLocked方法,ensureActivitiesVisibleLocked又调用makeVisibleAndRestartIfNeeded方法,来看下:

        private boolean makeVisibleAndRestartIfNeeded(ActivityRecord starting, int configChanges,
                boolean isTop, boolean andResume, ActivityRecord r) {
            // We need to make sure the app is running if it's the top, or it is just made visible from
            // invisible. If the app is already visible, it must have died while it was visible. In this
            // case, we'll show the dead window but will not restart the app. Otherwise we could end up
            // thrashing.
            if (isTop || !r.visible) {
                // This activity needs to be visible, but isn't even running...
                // get it started and resume if no other stack in this stack is resumed.
                if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Start and freeze screen for " + r);
                if (r != starting) {
                    r.startFreezingScreenLocked(r.app, configChanges);
                }
                if (!r.visible || r.mLaunchTaskBehind) {
                    if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Starting and making visible: " + r);
                    r.setVisible(true);
                }
                if (r != starting) {
                    // We should not resume activities that being launched behind because these
                    // activities are actually behind other fullscreen activities, but still required
                    // to be visible (such as performing Recents animation).
                    mStackSupervisor.startSpecificActivityLocked(r, andResume && !r.mLaunchTaskBehind,
                            true /* checkConfig */);
                    return true;
                }
            }
            return false;
        }
    

    看到最后调用了ActivityStackSupervisor的startSpecificActivityLocked方法:

        void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
            // Is this activity's application already running?
            final WindowProcessController wpc =
                    mService.getProcessController(r.processName, r.info.applicationInfo.uid);
    
            boolean knownToBeDead = false;
            if (wpc != null && wpc.hasThread()) {
                try {
                    realStartActivityLocked(r, wpc, andResume, checkConfig);
                    return;
                } catch (RemoteException e) {
                    Slog.w(TAG, "Exception when starting activity "
                            + r.intent.getComponent().flattenToShortString(), e);
                }
    
                // If a dead object exception was thrown -- fall through to
                // restart the application.
                knownToBeDead = true;
            }
    
            ...
        }
    

    接着调用了realStartActivityLocked方法:

        boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
                boolean andResume, boolean checkConfig) throws RemoteException {
        
                ...
    
                    // Create activity launch transaction.
                    final ClientTransaction clientTransaction = ClientTransaction.obtain(
                            proc.getThread(), r.appToken);
    
                    final DisplayContent dc = r.getDisplay().mDisplayContent;
                    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();
                    }
                    clientTransaction.setLifecycleStateRequest(lifecycleItem);
    
                    // Schedule transaction.
                    mService.getLifecycleManager().scheduleTransaction(clientTransaction);
    
                    ...
    
            return true;
        }
    

    中间有段代码如上,通过 ClientTransaction.obtain( proc.getThread(), r.appToken)获取了clientTransaction,其中参数proc.getThread()是IApplicationThread,就是前面提到的ApplicationThread在系统进程的代理。

    ClientTransaction是包含一系列的message的容器,message用于 发送到客户端,包含回调方法和生命周期状态。

    接着看,使用clientTransaction.addCallback添加了LaunchActivityItem实例:

        //都是用来发送到客户端的
        private List<ClientTransactionItem> mActivityCallbacks;
        
        public void addCallback(ClientTransactionItem activityCallback) {
            if (mActivityCallbacks == null) {
                mActivityCallbacks = new ArrayList<>();
            }
            mActivityCallbacks.add(activityCallback);
        }
    

    看下LaunchActivityItem实例的获取:

        /** Obtain an instance initialized with provided params. */
        public static LaunchActivityItem obtain(Intent intent, int ident, ActivityInfo info,
                Configuration curConfig, Configuration overrideConfig, CompatibilityInfo compatInfo,
                String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state,
                PersistableBundle persistentState, List<ResultInfo> pendingResults,
                List<ReferrerIntent> pendingNewIntents, boolean isForward, ProfilerInfo profilerInfo,
                IBinder assistToken) {
            LaunchActivityItem instance = ObjectPool.obtain(LaunchActivityItem.class);
            if (instance == null) {
                instance = new LaunchActivityItem();
            }
            setValues(instance, intent, ident, info, curConfig, overrideConfig, compatInfo, referrer,
                    voiceInteractor, procState, state, persistentState, pendingResults,
                    pendingNewIntents, isForward, profilerInfo, assistToken);
    
            return instance;
        }
    

    new了一个LaunchActivityItem然后设置各种值。我们从名字就能看出,它就是用来启动activity的。它是怎么发挥作用的呢?接着看:

    回到realStartActivityLocked方法,接着调用了mService.getLifecycleManager().scheduleTransaction(clientTransaction),mService是前面提到了ActivityTaskManagerService,getLifecycleManager()方法获取的是ClientLifecycleManager实例,它的scheduleTransaction方法如下:

        void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
            final IApplicationThread client = transaction.getClient();
            transaction.schedule();
            if (!(client instanceof Binder)) {
                transaction.recycle();
            }
        }
    

    就是调用ClientTransaction的schedule方法,那就看看:

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

    很简单,就是调用IApplicationThread的scheduleTransaction方法。由于IApplicationThread是ApplicationThread在系统进程的代理,所以真正执行的地方就是 客户端的ApplicationThread中了。也就是说,Activity启动的操作又跨进程的还给了客户端

    好了,到这里我们稍稍梳理下:启动Activity的操作从客户端 跨进程 转移到 AMS,AMS通过ActivityTaskManagerService、ActivityStarter、ActivityStack、ActivityStackSupervisor 对 Activity任务、activity栈、Activity记录 管理后,又用过跨进程把正在启动过程又转移到了客户端。

    线程切换及消息处理——mH

    接着上面的分析,我们找到ApplicationThread的scheduleTransaction方法:

            @Override
            public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
                ActivityThread.this.scheduleTransaction(transaction);
            }
    

    那就再看ActivityThread的scheduleTransaction方法,实际在其父类ClientTransactionHandler中:

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

    使用sendMessage发送消息,参数是ActivityThread.H.EXECUTE_TRANSACTION和transaction,接着看:

        void sendMessage(int what, Object obj) {
            sendMessage(what, obj, 0, 0, false);
        }
        private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
            if (DEBUG_MESSAGES) {
                Slog.v(TAG,
                        "SCHEDULE " + what + " " + mH.codeToString(what) + ": " + arg1 + " / " + obj);
            }
            Message msg = Message.obtain();
            msg.what = what;
            msg.obj = obj;
            msg.arg1 = arg1;
            msg.arg2 = arg2;
            if (async) {
                msg.setAsynchronous(true);
            }
            mH.sendMessage(msg);
        }
    

    最后调用了mH.sendMessage(msg),mH是个啥?我们看看:

    //ActivityThread
    final H mH = new H();
    
        class H extends Handler {
            public static final int BIND_APPLICATION        = 110;
            @UnsupportedAppUsage
            public static final int EXIT_APPLICATION        = 111;
            @UnsupportedAppUsage
            public static final int RECEIVER                = 113;
            @UnsupportedAppUsage
            public static final int CREATE_SERVICE          = 114;
            @UnsupportedAppUsage
            public static final int SERVICE_ARGS            = 115;
            @UnsupportedAppUsage
            public static final int STOP_SERVICE            = 116;
    
            public static final int CONFIGURATION_CHANGED   = 118;
            ...
            @UnsupportedAppUsage
            public static final int BIND_SERVICE            = 121;
            @UnsupportedAppUsage
            public static final int UNBIND_SERVICE          = 122;
            ...
            
            public static final int EXECUTE_TRANSACTION = 159;
            
            public static final int RELAUNCH_ACTIVITY = 160;
            public static final int PURGE_RESOURCES = 161;
    
            public void handleMessage(Message msg) {
                if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
                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;
                    case EXIT_APPLICATION:
                        if (mInitialApplication != null) {
                            mInitialApplication.onTerminate();
                        }
                        Looper.myLooper().quit();
                        break;
                    case RECEIVER:
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveComp");
                        handleReceiver((ReceiverData)msg.obj);
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                        break;
                    case CREATE_SERVICE:
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));
                        handleCreateService((CreateServiceData)msg.obj);
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                        break;
                    case BIND_SERVICE:
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
                        handleBindService((BindServiceData)msg.obj);
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                        break;
                    case UNBIND_SERVICE:
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceUnbind");
                        handleUnbindService((BindServiceData)msg.obj);
                        schedulePurgeIdler();
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                        break;
                    case SERVICE_ARGS:
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceStart: " + String.valueOf(msg.obj)));
                        handleServiceArgs((ServiceArgsData)msg.obj);
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                        break;
                    case STOP_SERVICE:
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStop");
                        handleStopService((IBinder)msg.obj);
                        schedulePurgeIdler();
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                        break;
                    case CONFIGURATION_CHANGED:
                        handleConfigurationChanged((Configuration) msg.obj);
                        break;
                        
                    ...
                    
                    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;
                    case RELAUNCH_ACTIVITY:
                        handleRelaunchActivityLocally((IBinder) msg.obj);
                        break;
                    case PURGE_RESOURCES:
                        schedulePurgeIdler();
                        break;
                }
                Object obj = msg.obj;
                if (obj instanceof SomeArgs) {
                    ((SomeArgs) obj).recycle();
                }
                if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
            }
        }
    

    mH是在创建ActivityThread实例时赋值的,是自定义Handler子类H的实例,也就是在ActivityThread的main方法中,并且初始化是已经主线程已经有了mainLooper,所以,使用这个mH来sendMessage就把消息发送到了主线程

    那么是从哪个线程发送的呢?那就要看看ApplicationThread的scheduleTransaction方法是执行在哪个线程了。根据IPC知识,我们知道,服务器的Binder方法运行在Binder的线程池中,也就是说系统进行跨进程调用ApplicationThread的scheduleTransaction就是执行在Binder的线程池中的了。

    到这里,消息就在主线程处理了,那么是怎么处理Activity的启动的呢?接着看。我们找到ActivityThread.H.EXECUTE_TRANSACTION这个消息的处理,就在handleMessage方法的倒数第三个case(就在上面代码):取出ClientTransaction实例,调用TransactionExecutor的execute方法,那就看看:

        public void execute(ClientTransaction transaction) {
            if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Start resolving transaction");
    
            final IBinder token = transaction.getActivityToken();
            ...
            executeCallbacks(transaction);
    
            executeLifecycleState(transaction);
            ...
        }
    

    继续跟进executeCallbacks方法:

        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);
                ...
                item.execute(mTransactionHandler, token, mPendingActions);
                item.postExecute(mTransactionHandler, token, mPendingActions);
                ...
            }
        }
    

    遍历callbacks,调用ClientTransactionItem的execute方法,而我们这里要关注的是ClientTransactionItem的子类LaunchActivityItem,看下它的execute方法:

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

    里面调用了client.handleLaunchActivity方法,client是ClientTransactionHandler的实例,是在TransactionExecutor构造方法传入的,TransactionExecutor创建是在ActivityThread中:

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

    所以,client.handleLaunchActivity方法就是ActivityThread的handleLaunchActivity方法。

    好了,到这里 ApplicationThread把启动Activity的操作,通过mH切到了主线程,走到了ActivityThread的handleLaunchActivity方法

    Activity启动核心实现——初始化及生命周期

    那就接着看:

        public Activity handleLaunchActivity(ActivityClientRecord r,
                PendingTransactionActions pendingActions, Intent customIntent) {
            ...
            final Activity a = performLaunchActivity(r, customIntent);
            ...
            return a;
        }
    

    继续跟performLaunchActivity方法,这里就是activity 启动的核心实现了:

        /**  activity 启动的核心实现. */
        private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
            //1、从ActivityClientRecord获取待启动的Activity的组件信息
            ActivityInfo aInfo = r.activityInfo;
            if (r.packageInfo == null) {
                r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                        Context.CONTEXT_INCLUDE_CODE);
            }
    
            ComponentName component = r.intent.getComponent();
            if (component == null) {
                component = r.intent.resolveActivity(
                    mInitialApplication.getPackageManager());
                r.intent.setComponent(component);
            }
    
            if (r.activityInfo.targetActivity != null) {
                component = new ComponentName(r.activityInfo.packageName,
                        r.activityInfo.targetActivity);
            }
            //创建ContextImpl对象
            ContextImpl appContext = createBaseContextForActivity(r);
            Activity activity = null;
            try {
                //2、创建activity实例
                java.lang.ClassLoader cl = appContext.getClassLoader();
                activity = mInstrumentation.newActivity(
                        cl, component.getClassName(), r.intent);
                StrictMode.incrementExpectedActivityCount(activity.getClass());
                r.intent.setExtrasClassLoader(cl);
                r.intent.prepareToEnterProcess();
                if (r.state != null) {
                    r.state.setClassLoader(cl);
                }
            } catch (Exception e) {
                ..
            }
            try {
                //3、创建Application对象(如果没有的话)
                Application app = r.packageInfo.makeApplication(false, mInstrumentation);
                ...
                if (activity != null) {
                    CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
                    Configuration config = new Configuration(mCompatConfiguration);
                    if (r.overrideConfig != null) {
                        config.updateFrom(r.overrideConfig);
                    }
                  
                    Window window = null;
                    if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
                        window = r.mPendingRemoveWindow;
                        r.mPendingRemoveWindow = null;
                        r.mPendingRemoveWindowManager = null;
                    }
                    appContext.setOuterContext(activity);
                    
                    //4、attach方法为activity关联上下文环境
                    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);
    
                    if (customIntent != null) {
                        activity.mIntent = customIntent;
                    }
                    r.lastNonConfigurationInstances = null;
                    checkAndBlockForNetworkAccess();
                    activity.mStartedActivity = false;
                    int theme = r.activityInfo.getThemeResource();
                    if (theme != 0) {
                        activity.setTheme(theme);
                    }
    
                    activity.mCalled = false;
                    
                    //5、调用生命周期onCreate
                    if (r.isPersistable()) {
                        mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                    } else {
                        mInstrumentation.callActivityOnCreate(activity, r.state);
                    }
                    if (!activity.mCalled) {
                        throw new SuperNotCalledException(
                            "Activity " + r.intent.getComponent().toShortString() +
                            " did not call through to super.onCreate()");
                    }
                    r.activity = activity;
                }
                r.setState(ON_CREATE);
                
                synchronized (mResourcesManager) {
                    mActivities.put(r.token, r);
                }
    
            } 
            ...
    
            return activity;
        }
    

    performLaunchActivity主要完成以下事情:

    1. 从ActivityClientRecord获取待启动的Activity的组件信息
    2. 通过mInstrumentation.newActivity方法使用类加载器创建activity实例
    3. 通过LoadedApk的makeApplication方法创建Application对象,内部也是通过mInstrumentation使用类加载器,创建后就调用了instrumentation.callApplicationOnCreate方法,也就是Application的onCreate方法。
    4. 创建ContextImpl对象并通过activity.attach方法对重要数据初始化,关联了Context的具体实现ContextImpl,attach方法内部还完成了window创建,这样Window接收到外部事件后就能传递给Activity了。
    5. 调用Activity的onCreate方法,是通过 mInstrumentation.callActivityOnCreate方法完成。

    到这里Activity的onCreate方法执行完,那么onStart、onResume呢?

    上面看到LaunchActivityItem,是用来启动Activity的,也就是走到Activity的onCreate,那么是不是有 "XXXActivityItem"呢? 有的:

    • LaunchActivityItem 远程App端的onCreate生命周期事务
    • ResumeActivityItem 远程App端的onResume生命周期事务
    • PauseActivityItem 远程App端的onPause生命周期事务
    • StopActivityItem 远程App端的onStop生命周期事务
    • DestroyActivityItem 远程App端onDestroy生命周期事务

    另外梳理过程中涉及的几个类:

    • ClientTransaction 客户端事务控制者
    • ClientLifecycleManager 客户端的生命周期事务控制者
    • TransactionExecutor 远程通信事务执行者

    那么我们再来看看ResumeActivityItem吧。

    我们再来重新看看在ActivityStackSupervisor的realStartActivityLocked方法:

        boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
                boolean andResume, boolean checkConfig) throws RemoteException {
                ...
                    // Create activity launch transaction.
                    final ClientTransaction clientTransaction = ClientTransaction.obtain(
                            proc.getThread(), r.appToken);
    
                    final DisplayContent dc = r.getDisplay().mDisplayContent;
                    clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                            System.identityHashCode(r), r.info,
                            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;
                    //这里ResumeActivityItem
                    if (andResume) {
                        lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
                    } else {
                        lifecycleItem = PauseActivityItem.obtain();
                    }
                    clientTransaction.setLifecycleStateRequest(lifecycleItem);
    
                    // Schedule transaction.
                    mService.getLifecycleManager().scheduleTransaction(clientTransaction);
    
                    ...
    
            return true;
        }
    

    前面只说了通过clientTransaction.addCallback添加LaunchActivityItem实例,在注意下面接着调用了clientTransaction.setLifecycleStateRequest(lifecycleItem)方法,lifecycleItem是ResumeActivityItem或PauseActivityItem实例,这里我们关注ResumeActivityItem,先看下setLifecycleStateRequest方法:

        /**
         * Final lifecycle state in which the client activity should be after the transaction is
         * executed.
         */
        private ActivityLifecycleItem mLifecycleStateRequest;
        
        public void setLifecycleStateRequest(ActivityLifecycleItem stateRequest) {
            mLifecycleStateRequest = stateRequest;
        }
    

    mLifecycleStateRequest表示执行transaction后的最终的生命周期状态。

    继续看处理ActivityThread.H.EXECUTE_TRANSACTION这个消息的处理,即TransactionExecutor的execute方法:

        public void execute(ClientTransaction transaction) {
            if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Start resolving transaction");
    
            final IBinder token = transaction.getActivityToken();
            ...
            executeCallbacks(transaction);
    
            executeLifecycleState(transaction);
            ...
        }
    

    前面我们关注的是executeCallbacks方法,现在看看executeLifecycleState方法:

        /** Transition to the final state if requested by the transaction. */
        private void executeLifecycleState(ClientTransaction transaction) {
            final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
            if (lifecycleItem == null) {
                // No lifecycle request, return early.
                return;
            }
    
            final IBinder token = transaction.getActivityToken();
            final ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
            ...
    
            // Execute the final transition with proper parameters.
            lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
            lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
        }
    

    这里取出了ActivityLifecycleItem并且调用了它的execute方法,实际就是ResumeActivityItem的方法:

        @Override
        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的handleResumeActivity方法:

        @Override
        public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
                String reason) {
            ...
            // performResumeActivity内部会走onStart、onResume
            final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
            if (r == null) {
                // We didn't actually resume the activity, so skipping any follow-up actions.
                return;
            }
            ...
            
            if (r.window == null && !a.mFinished && willBeVisible) {
                r.window = r.activity.getWindow();
                View decor = r.window.getDecorView();
                decor.setVisibility(View.INVISIBLE);
                ViewManager wm = a.getWindowManager();
                WindowManager.LayoutParams l = r.window.getAttributes();
                a.mDecor = decor;
                l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
                l.softInputMode |= forwardBit;
                if (r.mPreserveWindow) {
                    a.mWindowAdded = true;
                    r.mPreserveWindow = false;
                    
                    ViewRootImpl impl = decor.getViewRootImpl();
                    if (impl != null) {
                        impl.notifyChildRebuilt();
                    }
                }
                ...
                
            if (!r.activity.mFinished && willBeVisible && r.activity.mDecor != null && !r.hideForNow) {
                if (r.newConfig != null) {
                    performConfigurationChangedForActivity(r, r.newConfig);
                    if (DEBUG_CONFIGURATION) {
                        Slog.v(TAG, "Resuming activity " + r.activityInfo.name + " with newConfig "
                                + r.activity.mCurrentConfig);
                    }
                    r.newConfig = null;
                }
                if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward=" + isForward);
                WindowManager.LayoutParams l = r.window.getAttributes();
                if ((l.softInputMode
                        & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
                        != forwardBit) {
                    l.softInputMode = (l.softInputMode
                            & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
                            | forwardBit;
                    if (r.activity.mVisibleFromClient) {
                        ViewManager wm = a.getWindowManager();
                        View decor = r.window.getDecorView();
                        wm.updateViewLayout(decor, l);
                    }
                }
    
                r.activity.mVisibleFromServer = true;
                mNumVisibleActivities++;
                if (r.activity.mVisibleFromClient) {
                    //添加window、设置可见
                    r.activity.makeVisible();
                }
            }
    
            r.nextIdle = mNewActivities;
            mNewActivities = r;
            if (localLOGV) Slog.v(TAG, "Scheduling idle handler for " + r);
            Looper.myQueue().addIdleHandler(new Idler());
        }
    

    handleResumeActivity做了以下事情:

    1. 通过performResumeActivity方法,内部调用生命周期onStart、onResume(可以自行查看,这里不再扩展)
    2. 通过activity.makeVisible方法,添加window、设置可见。(所以视图的真正可见是在onResume方法之后)

    好了,到这里就是真正创建完成并且可见了。

    总结

    关于Activity启动的流程的讲解,我们分成了几个阶段:启动的发起、AMS的管理、线程切换、启动核心实现,知道了启动过程经历了两次IPC,客户端到AMS、AMS到客户端,以及Activity创建和生命周期的执行。

    好了,今天就到这里,欢迎留言讨论~

    欢迎关注我的公众号 公众号

    相关文章

      网友评论

        本文标题:Activity的启动过程详解(基于10.0源码)

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