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

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

探索7.x, 全面解析Activity启动框架 (1)_第1张图片
Activity的启动框架

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

探索7.x, 全面解析Activity启动框架 (1)_第2张图片
Android

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

探索7.x, 全面解析Activity启动框架 (1)_第3张图片
Activity

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

Activity的启动框架图

探索7.x, 全面解析Activity启动框架 (1)_第4张图片
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!

你可能感兴趣的:(探索7.x, 全面解析Activity启动框架 (1))