重温四大组件(三)—Activity的启动过程

前言

重温四大组件第四篇,这里分析一下Activity的启动过程。Activity的启动过程分为两种,一种是根Activity的启动,另一种是普通Activity的启动过程。根Activity也就是默认启动的Activity(在AndroidMinifest.xml配置的启动Activity)。普通Activity指的是除根Activity的其余Activity。其中根Activity和普通Activity的启动过程略有区别,根Activity的启动过程涉及到了应用程序进程的启动过程。java

接下来从根Activity的角度启动来讲。android

如下分析的代码基于Android 9.0数据结构

Activity启动过程当中的数据结构

咱们在看一些技术博客的时候常常会看到一些分析AMS的文章。AMS就是ActivityManagerService,顾名思义就是Activity的管理服务,但它不只仅管理Activity,其余三个组件的启动也经由AMS。同时,在看Activity的启动过程以前,咱们应该了解一些Binder的知识。Binder是Android系统中一种跨进程通讯技术。在Activity的启动过程当中就涉及到了Binder通讯的过程。app

Activity的启动过程,能够归纳为Launcher到AMS(通过Binder通讯),从AMS到ApplicationThread(经过Binder通讯)。ide

以上介绍了AMS在Activity的启动中承担的做用。接下来,咱们再介绍一些在Activity启动过程当中的一些其余角色。函数

ActivityStack

从ActivityStack的命名能够看出这个是Activity栈相关的。它的做用是管理和记录一个Activity栈的Activity。接下来咱们看下ActivityStack中有哪些属性。post

名称 类型 说明
mService ActivityManagerService 目前AMS的引用
mRecentTasks RecentTasks 记录一个最近使用的Activity列表
mPausingActivity ActivityRecord 目前中止状态的Activity信息
mResumedActivity ActivityRecord 目前resume状态的Activity信息

ActivityRecord

ActivityRecord是用来描述一个Activity的数据结构,它记录了Activity的全部信息。学习

名称 类型 说明
service ActivityManagerService 目前AMS的引用
info ActivityInfo 主要记录了Activity在Manifest文件中的配置信息
launchedFromPid int 启动Activity进程的pid
launchedFromUid int 启动Activity进程的uid
taskAffinity String Activity启动后所在的task
task TaskRecord 记录了所在task的信息
app ProcessRecord 记录了Activity启动所在进程的信息
state ActivityState 当前Activity的状态
theme int Activity的主题

TaskRecord

TaskRecord是关于任务栈的描述。ui

名称 类型 说明
taskId final int 任务栈的惟一标识
affinity String 任务栈的名称,也就是taskAffinity配置的名称
intent Intent 启动这个任务栈的Intent
mActivities ArrayList 按照在任务栈中历史顺序排序的Activity
mStack ActivityStack 任务栈所在的Activity栈
mService ActivityManagerService 目前AMS的引用

ProcessRecord

ProcessRecord是关于应用进程的描述。this

名称 类型 说明
uid int 进程的uid
processName String 进程名称
info ApplicationInfo 记录应用程序信息

在上面介绍了Activity启动过程当中关于Activity启动过程当中的一些信息记录。好比:Activity栈信息、任务栈信息以及进程信息等。

Activity的启动工程

Activity的启动过程是一个很复杂的过程,接下来的分析过程并不会把全部细节都分析到位。咱们分析Activity的启动过程主要是为了学习Android系统对Activity组件的管理过程以及对应用进程的调度。

从Launcher到AMS

咱们知道在Android系统中锁呈现的桌面就是一个应用程序。当用户点击桌面上的应用图标是就能够启动相应的应用程序。应用程序由Launcher启动,调用startActivitySafely()方法。

/**Launcher.java**/
 boolean startActivitySafely(Intent intent, Object tag) {
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        try {
            startActivity(intent);
            return true;
        } catch (ActivityNotFoundException e) {
            Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
        } catch (SecurityException e) {
            Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
        }
        return false;
    }
复制代码

能够看到在startActivitySafely()中继续调用startActivity()方法启动Activity,而且在Intent中设置了flag为FLAG_ACTIVITY_NEW_TASK表示Activity将在一个新的任务栈中启动。这个方法就是在Activity中的。

/**Activity.java**/
public void startActivity(Intent intent, @Nullable Bundle options) {
        if (options != null) {
            startActivityForResult(intent, -1, options);
        } else {
            // Note we want to go through this call for compatibility with
            // applications that may have overridden the method.
            startActivityForResult(intent, -1);
        }
    }
复制代码

这里继续调用了startActivityForResult(),而且requestCode为-1表示Launcher不须要知道Activity的结果。

/**Activity.java**/
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode, @Nullable Bundle options) {
        if (mParent == null) {
            options = transferSpringboardActivityOptions(options);
            //继续启动Activity
            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 {
            if (options != null) {
                mParent.startActivityFromChild(this, intent, requestCode, options);
            } else {
                mParent.startActivityFromChild(this, intent, requestCode);
            }
        }
    }
复制代码

在这里先判断mParent是否为null,而后根据结果选择走那一步。若是跟代码的话,能够看到mParent在attach()方法中或者setParent()方法中赋值,在根Activity的状况中mParent为null。因此继续调用 mInstrumentation.execStartActivity()。

/**Instrumentation.java**/
public ActivityResult execStartActivity( Context who, IBinder contextThread, IBinder token, String target, Intent intent, int requestCode, Bundle options) {
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        //......
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(who);
            //经过Binder接口获取AMS对象
            int result = ActivityManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target, requestCode, 0, null, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }
复制代码

在上面的方法中继续启动Activity,在这里咱们能够看到经过ActivityManager.getService()咱们就获取到了AMS对象。接下来,咱们看下AMS的获取过程。

/**ActivityManager.java**/
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;
                }
            };
复制代码

在getService()方法中经过IActivityManagerSingleton获取了AMS的对象。在建立IActivityManagerSingleton的方法中咱们能够看到返回的是IActivityManager,IActivityManager就是使用了AIDL的方式生成的。

在AMS中处理Activity的启动

从这里开始,Activity的启动就开始在AMS中进行了。从上面的代码能够知道这个过程是经过Binder通讯方式进行的。

/**ActivityManagerService.java**/
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());
    }
复制代码

在ActivityManagerService中经过startActivity()方法继续进行Activity的启动。接下来咱们直接看最终的方法回调。

/**ActivityManagerService.java**/
public final 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) {
        //......
        //从obtainStarter()中获取了ActivityStarter对象
        return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
                .setCaller(caller)
                .setCallingPackage(callingPackage)
                .setResolvedType(resolvedType)
                .setResultTo(resultTo)
                .setResultWho(resultWho)
                .setRequestCode(requestCode)
                .setStartFlags(startFlags)
                .setProfilerInfo(profilerInfo)
                .setActivityOptions(bOptions)
                .setMayWait(userId) //设置mayWait标志
                .execute();

    }
复制代码

在上面的方法中,AMS经过startActivityAsUser()方法最终把Activity的启动过程转移到了ActivityStarter中。咱们直接看下ActivityStarter的execute()方法。

/**ActivityStarter**/
int execute() {
        try {
            if (mRequest.mayWait) {
                return startActivityMayWait(mRequest.caller, mRequest.callingUid,
                       //....//);
            } else {
                return startActivity(mRequest.caller, mRequest.intent, //....//);
            }
        } finally {
            onExecutionComplete();
        }
    }
复制代码

这里根据mRequest.mayWait(表示咱们应该等待启动请求的结果。)中的标志来判断走哪一个逻辑分支。在上面的代码中调用setMayWait(userId),这里将mayWait设置为true。那么接下来咱们继续看startActivityMayWait()方法。

private int startActivityMayWait(//....//) {
        //......
        // Collect information about the target of the Intent.
        ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo); //构建Activity的信息

        synchronized (mService) {
            final ActivityStack stack = mSupervisor.mFocusedStack; //获取Activity栈的信息
            stack.mConfigWillChange = globalConfig != null
                    && mService.getGlobalConfiguration().diff(globalConfig) != 0;
            //......
            final ActivityRecord[] outRecord = new ActivityRecord[1]; //获取Activity的信息
            //继续启动Activity
            int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
                    voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
                    callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
                    ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
                    allowPendingRemoteAnimationRegistryLookup);

            Binder.restoreCallingIdentity(origId);
            //......
            return res;
        }
    }
复制代码

咱们继续跟代码,接下会调用

private int startActivity(//....//) {
        //......
        ProcessRecord callerApp = null; //获取进程信息
        if (caller != null) {
            //caller是ActivityThread中的Binder接口,用过应用程序进程则不为null
            callerApp = mService.getRecordForAppLocked(caller); //获取进程信息
            if (callerApp != null) {
                callingPid = callerApp.pid;
                callingUid = callerApp.info.uid;
            } 
        }
        //......
        //建立启动Activity的信息类
        ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
                callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
                resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
                mSupervisor, checkedOptions, sourceRecord);
        if (outActivity != null) {
            outActivity[0] = r;
        }
        final ActivityStack stack = mSupervisor.mFocusedStack; //获取有焦点的Activity栈
        //......
        //继续启动Activity
        return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
                true /* doResume */, checkedOptions, inTask, outActivity);
    }
复制代码

在上面会看到根据IApplicationThread获取应用进程信息,这里若是应用进程没有被建立的时候,IApplicationThread是null,而后接下来的步骤会建立应用程序进程,这里再也不详细说。接下来继续进行Activity启动的分析。

private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask, ActivityRecord[] outActivity) {
        //......
        int result = START_SUCCESS;
            if (mDoResume) {
            final ActivityRecord topTaskActivity =
                    mStartActivity.getTask().topRunningActivityLocked();
            if (!mTargetStack.isFocusable()
                    || (topTaskActivity != null && topTaskActivity.mTaskOverlay
                mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
                mService.mWindowManager.executeAppTransition();
            } else {
                if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) {
                    mTargetStack.moveToFront("startActivityUnchecked");
                }
                //这里继续启动Activity
                mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
                        mOptions);
            }
        }
        return START_SUCCESS;
    }
复制代码

接下来启动Activity的过程转到ActivityStackSupervisor中。

/**ActivityStackSupervisor**/
boolean resumeFocusedStackTopActivityLocked( ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
        //这里从Activity栈中启动
        if (targetStack != null && isFocusedStack(targetStack)) {
            return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        }
        //......
        return false;
    }
复制代码

上面的代码中继续启动Activity,此次启动过程转到ActivityStack中。

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
        //......省略代码
      
       boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, false);
        if (mResumedActivity != null) {
            //这里若是mResumedActivity不为null,就中止mResumedActivity
            if (DEBUG_STATES) Slog.d(TAG_STATES,
                    "resumeTopActivityLocked: Pausing " + mResumedActivity);
            pausing |= startPausingLocked(userLeaving, false, next, false);
        }
        //next是ActivityRecord对象,next.app是ProcessRecord对象,next.app.thread是IApplicationThread
        if (next.app != null && next.app.thread != null) {
            //若是都不为null,说明应用进程已经被建立
           //......
            synchronized(mWindowManager.getWindowManagerLock()) {
                try {
                    mStackSupervisor.startSpecificActivityLocked(next, true, false);
                    return true;
                }
            }
        } else {
            ////应用进程没有被建立
            mStackSupervisor.startSpecificActivityLocked(next, true, true);
        }
        return true;
    }
复制代码

在上面的代码中咱们能够看到有一个判断逻辑if (next.app != null && next.app.thread != null),这个是判断应用程序进程是否被建立,从代码中能够看到,不管应用进程是否被建立,都会调用startSpecificActivityLocked()方法。这里Activity的启动又转移到了ActivityStackSupervisor中。

除此以外,还有一个步骤是将mResumedActivity设置为中止状态,在咱们查看Activity的生命周期时,一个Activity启动另一个Activity的时候,在调用过Activity的pause生命周期函数时才会开始下一个Activity的生命周期。

/**ActivityStackSupervisor**/
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
        // Is this activity's application already running?
        //获取应用进程信息
        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true);
        if (app != null && app.thread != null) {
            try {
                if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                        || !"android".equals(r.info.packageName)) {
                    app.addPackage(r.info.packageName, r.info.applicationInfo.longVersionCode,
                            mService.mProcessStats);
                }
                //继续启动Activity
                realStartActivityLocked(r, app, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
                
            }
        }
        //建立应用进程
        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
    }
复制代码

这里就看到了若是应用进程不存在就会经过AMS建立应用进程,这里再也不展开分析。若是应用进程存在就继续启动Activity。调用了realStartActivityLocked方法。

/**ActivityStackSupervisor**/ 
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException {
                //......
                // Create activity launch transaction.
                //Android 9.0的启动方式与其余版本的不一样,这里换成了经过ClientTransaction的方式已启动。
                final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
                        r.appToken);
                clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                        System.identityHashCode(r), r.info,
                        // TODO: Have this take the merged configuration instead of separate global
                        // and override configs.
                        mergedConfiguration.getGlobalConfiguration(),
                        mergedConfiguration.getOverrideConfiguration(), r.compat,
                        r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
                        r.persistentState, results, newIntents, mService.isNextTransitionForward(),
                        profilerInfo));

                // 这里用来处理Activity生命周期回调
                final ActivityLifecycleItem lifecycleItem;
                if (andResume) {
                    lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
                } else {
                    lifecycleItem = PauseActivityItem.obtain();
                }
                clientTransaction.setLifecycleStateRequest(lifecycleItem);

                // Schedule transaction.
                mService.getLifecycleManager().scheduleTransaction(clientTransaction);
                ...

        return true;
    }
复制代码

在上面能够看到Android 9.0的启动方式与其余版本的不一样,在Android 9.0里主要经过回调的方式启动Activity,最终会经过AMS中的ClientLifecycleManager.scheduleTransaction()方法调用ApplicationThread的scheduleTransaction(),最后的是执行的LaunchActivityItem的execute()方法。

/**TransactionExecutor**/
public void execute(ClientTransaction transaction) {
        final IBinder token = transaction.getActivityToken();
        //1.先执行CallBack
        executeCallbacks(transaction);
        //2.再执行Activity生命周期回调
        executeLifecycleState(transaction);
        mPendingActions.clear();
    }
复制代码
/**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);
        client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }
复制代码

能够看到这里调用了ClientTransactionHandler的handleLaunchActivity()方法。从这里Activity的启动过程就从AMS中的调用切换到了ActivityThread中去了。

从AMS到ActivityThread

上面说到,Activity的启动调用了ClientTransactionHandler的handleLaunchActivity()方法。咱们能够发现ActivityThread是继承自ClientTransactionHandler的。在ClientTransactionHandler中handleLaunchActivity是抽象方法,咱们直接在ActivityThread中看。

从这里开始将开始执行Activity的生命周期函数。

/**ActivityThread**/
public Activity handleLaunchActivity(ActivityClientRecord r, PendingTransactionActions pendingActions, Intent customIntent) {
        //......
        //初始化WindowManagerService
        WindowManagerGlobal.initialize();
        final Activity a = performLaunchActivity(r, customIntent);
        //......
        return a;
    }
复制代码

能够看到在这里继续调用了

/**ActivityThread**/
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
       //......
        Activity activity = null;
        try {
            //获取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 {
            //初始化Application
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);

            if (activity != null) {
                //设置Context
                appContext.setOuterContext(activity);
                //调用Activity的attach()方法
                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()) {
                    //调用onCreate()生命周期函数
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.mInstrumentation(activity, r.state);
                }
                //......
                int theme = r.activityInfo.getThemeResource();
                if (theme != 0) {
                    activity.setTheme(theme); //设置主题
                }
                //......
                r.activity = activity;
            }
            r.setState(ON_CREATE);
        }
        //......
        return activity;
    }
复制代码

在上面的代码能够看到执行完Activity的attach()方法后,继续执行Instrumentation的callActivityOnCreate()方法。

/**Instrumentation**/
public void callActivityOnCreate(Activity activity, Bundle icicle) {
        prePerformCreate(activity);
        activity.performCreate(icicle);
        postPerformCreate(activity);
    }
复制代码

这里能够看到,又执行了Activity的performCreate()方法。

/****/
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
        //....
        //调用onCreate()生命周期方法
        if (persistentState != null) {
            onCreate(icicle, persistentState);
        } else {
            onCreate(icicle);
        }
    }
复制代码

在上面的代码中调用了Activity的onCreate()生命周期方法。到这里,在上面讲到的TransactionExecutor的execute()方法中的回调已经执行完毕,接下来就是开始执行生命周期相关的回调。

咱们在分析上面代码的时候知道,生命周期回调是一个ResumeActivityItem。

/**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);
    }
复制代码

能够看到这里有调用了handleResumeActivity()方法。

public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward, String reason) {
      
        final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason); 
    }
复制代码
public ActivityClientRecord performResumeActivity(IBinder token, boolean finalStateRequest, String reason) {
            //执行Activity的performResume
            r.activity.performResume(r.startsNotResumed, reason);

            r.state = null;
            r.persistentState = null;
            r.setState(ON_RESUME);
        } catch (Exception e) {
          
        }
        return r;
    }
复制代码

在上面的代码中调用了Activity的performResume()方法。进而调用Activity的onResume()方法。这时Activity就呈现到了界面。Activity也算启动完成。

总结

上面以根Activity的视角分析了Activity的启动过程。整个分析下来,感受到Activity的启动仍是十分复杂的,可是在也并不须要面面俱到,可以把握大致,流程理解Android在启动Activity的过程当中是怎么调度的,这样就达到了咱们的目的。

相关文章
相关标签/搜索