探索7.x, 全面解析Activity启动框架 (1)

欢迎Follow我的GitHub, 关注我的简书, 博客目录.

Activity的启动框架

本文的合集已经编著成书,高级Android开发强化实战,欢迎各位读友的建议和指导。在京东即可购买:https://item.jd.com/12385680.html

Android

无论怎么说, Activity都是Android最核心的组件, 主要负责向用户展示应用信息. Activity的生命周期由Android系统控制, 启动与绘制都是自动完成. 对于开发人员而言, 仅仅是一句startActivity, 就完成了全部, 但是在平凡的表象下隐藏着惊人的秘密. 让我们拨开迷雾, 一起探索Activity的启动框架! Know more the world, know more ourselves.

Activity

本文源码来源Android SDK 25(即7.1), 逻辑与低版本不同. 在AMS与ASS之间又添加ActivityStarter, 负责管理Activity的启动.

Activity的启动框架图

Activity的启动框架

Activity与Instrumentation

最简单的Activity启动方式, 如下:

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

startActivity方法存在于Activity类中, Activity类的调用流程:

  1. Activity#startActivity(Intent)
  2. Activity#startActivityForResult(Intent, int, Bundle)

Activity#startActivityForResult核心是mInstrumentation.execStartActivity

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
        @Nullable Bundle options) {
    if (mParent == null) {
        // ...
        Instrumentation.ActivityResult ar =
            mInstrumentation.execStartActivity(
                this, mMainThread.getApplicationThread(), mToken, this,
                intent, requestCode, options); // 核心方法
        // ...
    } else {
        // ...
    }
}

Instrumentation类负责监控系统与应用之间的交互.

execStartActivity核心是ActivityManagerNative类的getDefault#startActivity, 获取IActivityManager单例, 本质是ServiceManager.getService("activity"), 即ActivityManagerService. 通过Binder, 远程调用ActivityManagerService类的startActivity方法.

public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options) {
    // ...
    try {
        // ...
        int result = ActivityManagerNative.getDefault()
            .startActivity(whoThread, who.getBasePackageName(), intent,
                    intent.resolveTypeIfNeeded(who.getContentResolver()),
                    token, target != null ? target.mEmbeddedID : null,
                    requestCode, 0, null, options); // 核心方法
        // ...
    } // ...
    return null;
}

Activity启动通过远程调用, 由当前应用交给ActivityManagerService(AMS)处理.


ActivityManagerService

ActivityManagerService类是负责启动Activity的核心服务, 简称AMS. 启动逻辑包含在ActivityStarter, ActivityStackSupervisor和ActivityStack和三个类中, ActivityStarter负责启动, ActivityStackSupervisor负责管理Stack和TaskRecord, ActivityStack负责管理栈内的Activity.

Stack和TaskRecord示例:

  Stack #1:
    Running activities (most recent first):
      TaskRecord{3caa65e3 #2711 A=me.chunyu.spike.wcl_activity_launchmode_demo U=0 sz=2}
        Run #1: ActivityRecord{36b06e99 u0 me.chunyu.spike.wcl_activity_launchmode_demo/.TestAActivity t2711}
        Run #0: ActivityRecord{27396226 u0 me.chunyu.spike.wcl_activity_launchmode_demo/.MainActivity t2711}
  Stack #0:
    Running activities (most recent first):
      TaskRecord{27d796c9 #2695 A=com.miui.home U=0 sz=1}
        Run #0: ActivityRecord{2e5712cb u0 com.miui.home/.launcher.Launcher t2695}

ActivityManagerService类的调用过程:

  1. ActivityManagerService#startActivity
  2. ActivityManagerService#startActivityAsUser

ActivityManagerService调用ActivityStarterstartActivityMayWait方法, 执行启动.

@Override
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) {
    // ...
    return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
            resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
            profilerInfo, null, null, bOptions, false, userId, null, null);
}

ActivityStarter类负责处理Activity的Intent和Flags的逻辑, 还有管理Stack和TaskRecord.

ActivityStarter类的调用流程:

  1. ActivityStarter#startActivityMayWait
  2. ActivityStarter#startActivityLocked
  3. ActivityStarter#startActivityUnchecked

startActivityMayWait: 根据Intent获取Activity的启动信息(ResolveInfo和ActivityInfo), 获取调用者的Pid和Uid.
startActivityLocked: 创建ActivityRecord, 含有Activity的核心信息.
startActivityUnchecked: 根据启动的Flag信息, 设置TaskRecord, 完成后执行ActivityStackSupervisor类的resumeFocusedStackTopActivityLocked方法, 继续启动.

private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask) {
    // ...
    // 所有启动准备完成后, dontStart是true.
    final boolean dontStart = top != null && mStartActivity.resultTo == null
            && top.realActivity.equals(mStartActivity.realActivity)
            && top.userId == mStartActivity.userId
            && top.app != null && top.app.thread != null
            && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
            || mLaunchSingleTop || mLaunchSingleTask);
    if (dontStart) {
        ActivityStack.logStartActivity(AM_NEW_INTENT, top, top.task);
        // doResume是true, mDoResume也是true 
        if (mDoResume) {
            mSupervisor.resumeFocusedStackTopActivityLocked();
        }
        // ...
    }
    // ...
}

ActivityStackSupervisor类ActivityStack类配合使用. ActivityStackSupervisor负责管理Task和Stack, 而ActivityStack负责管理在Stack和Task中的Activity. 因此, 对于Stack和Task的操作, AMS使用ActivityStackSupervisor进行管理; 对于Activity的操作, AMS使用ActivityStack进行管理. 两者相互调用, 最终完成启动Activity.

ActivityStackSupervisor类ActivityStack类的调用流程:

  1. ActivityStackSupervisor#resumeFocusedStackTopActivityLocked
  2. ActivityStack#resumeTopActivityUncheckedLocked
  3. ActivityStack#resumeTopActivityInnerLocked
  4. ActivityStackSupervisor#startSpecificActivityLocked

核心在于ActivityStack类的resumeTopActivityInnerLocked方法, 根据ActivityRecord和ActivityOptions完成Activity的切换, 移至栈顶, 最后调用ActivityStackSupervisor类的startSpecificActivityLocked方法, 执行启动.

ActivityStackSupervisor类的startSpecificActivityLocked方法调用realStartActivityLocked方法, 执行真正的启动Activity.

void startSpecificActivityLocked(ActivityRecord r,
        boolean andResume, boolean checkConfig) {
    // 获取启动Activity的进程, 即Application
    ProcessRecord app = mService.getProcessRecordLocked(r.processName,
            r.info.applicationInfo.uid, true);
    r.task.stack.setLaunchTime(r);

    if (app != null && app.thread != null) {
        try {
            // ...
            // 真正启动Activity的过程
            realStartActivityLocked(r, app, andResume, checkConfig);
            return;
        }
        // ...
    }
    // ...
}

ActivityStackSupervisorrealStartActivityLocked方法中, 含有启动的核心方法scheduleLaunchActivity, 即调用IApplicationThreadscheduleLaunchActivity方法.

app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
        System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
        new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage,
        task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
        newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);

IApplicationThread的实现是ApplicationThread, 而ApplicationThread是ActivityThread的内部类, 即使用ApplicationThread类的scheduleLaunchActivity方法处理Activity启动.

最终由ActivityThread完成Activity的创建与绘制.


复杂的逻辑...

That's all! Enjoy it!

推荐阅读更多精彩内容