源码分析:Activity的启动过程(1)

Activity#startActivityForResult

我们从Activity的startActivity方法开始分析,该方法有几种重载方式,但最终都会调用startActivityForResult方法,该方法实现如下:

    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);    //先看Instrumentation的execStartActivity方法(exec是execute的缩写,意为执行)
            //...
        } else {
            //...
        }
    }

我们看下Instrumentation的execStartActivity方法

Instrumentation#execStartActivity(API25)

  • Instrumentation类相当于一个管家,它的职责是管理各个应用程序和系统的交互,Instrumentation将在任何应用程序运行前初始化,每个进程只会存在一个Instrumentation对象,且每个Activity都有此对象的实际引用,可以通过它监测系统与应用程序之间的所有交互。
  • 这里可以看到真正启动Activity的方法
    public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {

        //...

        try {
            //...

            //真正启动Activity
            int result = ActivityManagerNative.getDefault() //ActivityManagerNative.getDefault()返回一个IActivityManager接口对象
                .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;
    }
  • 其中,IActivityManager接口的具体实现是ActivityManagerService(下面简称AMS)。AMS继承自ActivityManagerNative,而ActivityManagerNative继承自Binder并实现了IActivityManager,所以AMB也是一个Binder。不过在API26中,AMS不再继承AMN,而是继承IActivityManager.Stub。(注意:在API26中,AMN被弃用,其内部的代理类ActivityManagerProxy已经被删除。这是因为在API26启动Activity的时候,和AMS的通信机制已经被改成AIDL方式,详情请参考该博客

ActivityManagerNative.getDefault()

    static public IActivityManager getDefault() {
        return gDefault.get();
    }

其中gDefault的定义如下:

    private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            IBinder b = ServiceManager.getService("activity");
            IActivityManager am = asInterface(b);
            return am;
        }
    };

Singleton是一个单例的封装类,第一次调用它的get方法时它会通过create方法来创建对象,在后续的调用中则直接返回之前创建的对象。

Instrumentation#execStartActivity(API26)

在API26中,真正启动Activity的代码发生了一些变化

    //ActivityManager.getService()返回 IActivityManager对象
    int result = ActivityManager.getService()
        .startActivity(whoThread, who.getBasePackageName(), intent,
                intent.resolveTypeIfNeeded(who.getContentResolver()),
                token, target != null ? target.mEmbeddedID : null,
                requestCode, 0, null, options);

ActivityManager.getService()

看下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);
                    //其中,Context.ACTIVITY_SERVICE = "activity";
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);
                    return am;
                }
            };

可以看出,高低版本都是先获取服务端(系统进程)中的AMS的IBinder对象,然后通过得到的IBinder对象来生成IActivityManager(系统进程中的AMS在app进程中的binder代理)

ActivityManagerService#startActivity

虽然不同版本的实现有所不同,但最终都是返回IActivityManager接口对象,而IActivityManager接口的实现类为AMS,所以最终调用的是AMS的startActivity方法

    @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 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) {
        //...
        // TODO: Switch to user app stacks here.
        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
                profilerInfo, null, null, bOptions, false, userId, null, null);
    }
  • 其中mActivityStarter是一个ActivityStarter对象,ActivityStarter类主要负责处理Activity的Intent和Flags, 还有关联相关的Stack和TaskRecord。
  • 在API23及以前版本中,return那里是调用ActivityStackSupervisor的startActivityMayWait方法的(该方法的实现和ActivityStarter一样,不如说是ActivityStarter照搬该方法)
    return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
            resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
            profilerInfo, null, null, options, false, userId, null, null);

但是在API24中,ActivityStackSupervisor移除了startActivityMayWait方法,该方法到了ActivityStarter中。

又继续调用了几个方法

ActivityStarter#startActivityMayWait

  • startActivityMayWait: 根据Intent获取Activity的启动信息(ResolveInfo和ActivityInfo), 获取调用者的Pid和Uid(CallingPid和CallingUid)
  • startActivityMayWait继续调用startActivityLocked方法
    //...
    int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
            aInfo, rInfo, voiceSession, voiceInteractor,
            resultTo, resultWho, requestCode, callingPid,
            callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
            options, ignoreTargetSecurity, componentSpecified, outRecord, container,
            inTask);
    //...
    return res;

ActivityStarter#startActivityLocked

  • startActivityLocked: 创建ActivityRecord, 含有Activity的核心信息
  • startActivityLocked继续调用startActivityUnchecked方法
    //...
    try {
        //...
        err = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
                true, options, inTask);
    }
    //...
    return err;

ActivityStarter#startActivityUnchecked

  • startActivityUnchecked:根据启动的Flag信息, 设置TaskRecord, 完成后执行ActivityStackSupervisor类的resumeFocusedStackTopActivityLocked方法, 继续启动。
    //...

    // 所有启动准备完成后, 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) {
        //...
        if (mDoResume) {
            mSupervisor.resumeFocusedStackTopActivityLocked();  //mSupervisor是一个ActivityStackSupervisor对象
        }
        //...
    }

ActivityStackSupervisor和ActivityStack之间的相互跳转

ActivityStackSupervisor#resumeFocusedStackTopActivityLocked

    boolean resumeFocusedStackTopActivityLocked() {
        return resumeFocusedStackTopActivityLocked(null, null, null);
    }
    boolean resumeFocusedStackTopActivityLocked(
            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
        if (targetStack != null && isFocusedStack(targetStack)) {
            return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
            //targetStack是一个ActivityStack对象
        }
        final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
        if (r == null || r.state != RESUMED) {
            mFocusedStack.resumeTopActivityUncheckedLocked(null, null); //mFocusedStack也是一个ActivityStack对象
        }
        return false;
    }

又调用了ActivityStack的resumeTopActivityUncheckedLocked方法

ActivityStack#resumeTopActivityUncheckedLocked

    boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
        if (mStackSupervisor.inResumeTopActivity) {
            // Don't even start recursing.
            return false;
        }
        boolean result = false;
        try {
            // Protect against recursion.
            mStackSupervisor.inResumeTopActivity = true;
            if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {
                mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;
                mService.updateSleepIfNeededLocked();
            }
            result = resumeTopActivityInnerLocked(prev, options); //调用resumeTopActivityInnerLocked方法
        } finally {
            mStackSupervisor.inResumeTopActivity = false;
        }
        return result;
    }

最后返回的result的值是通过调用resumeTopActivityInnerLocked方法获得的

ActivityStack#resumeTopActivityInnerLocked

    mStackSupervisor.startSpecificActivityLocked(next, true, false);   
    //mStackSupervisor是一个ActivityStackSupervisor对象

又调用了ActivityStackSupervisor的startSpecificActivityLocked方法

ActivityStackSupervisor#startSpecificActivityLocked

    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);
        r.task.stack.setLaunchTime(r);
        if (app != null && app.thread != null) {
            try {
                //...

                //真正启动activity的过程
                realStartActivityLocked(r, app, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
                //...
            }
        }
        //...
    }

终于,这里调用了realStartActivityLocked方法真正启动activity

API23及以前版本的一些区别

  • 在看《Android开发艺术探索》的时候,发现AMS的startActivityAsUser是调用ActivityStackSupervisor类的startActivityMayWait方法,这也导致后面一些方法调用的不同。

ActivityStackSupervisor#startActivityMayWait

这里的逻辑和API24版本是一样的,只不过调用的是ActivityStackSupervisor类的startActivityLocked方法

    //...

    int res = startActivityLocked(caller, intent, resolvedType, aInfo,
            voiceSession, voiceInteractor, resultTo, resultWho,
            requestCode, callingPid, callingUid, callingPackage,
            realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity,
            componentSpecified, null, container, inTask);
    //...

    return res;

ActivityStackSupervisor#startActivityLocked

    //...

    err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,
            startFlags, true, options, inTask);

    //...

    return err;

这里是又继续调用startActivityUncheckedLocked方法(和API24的名字不同,不过参数是一样的)

ActivityStackSupervisor#startActivityUncheckedLocked

    //省略无关代码

    if (doResume) {
        targetStack.resumeTopActivityLocked(null, options);
    }
    if (doResume) {
        targetStack.resumeTopActivityLocked(null);  //targetStack是一个ActivityStack对象
    }

又继续调用ActivityStack的resumeTopActivityLocked方法

ActivityStack#resumeTopActivityLocked

    final boolean resumeTopActivityLocked(ActivityRecord prev) {
        return resumeTopActivityLocked(prev, null);
    }
    final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
        if (mStackSupervisor.inResumeTopActivity) {
            // Don't even start recursing.
            return false;
        }
        boolean result = false;
        try {
            // Protect against recursion.
            mStackSupervisor.inResumeTopActivity = true;
            if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {
                mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;
                mService.updateSleepIfNeededLocked();
            }
            result = resumeTopActivityInnerLocked(prev, options);
        } finally {
            mStackSupervisor.inResumeTopActivity = false;
        }
        return result;
    }

可以看出,该方法和API24以后的resumeTopActivityUncheckedLocked方法的实现是一样的,只是名字不同,而之后的调用就和API24以后一样了。

小结

  • 总的来说,从API24开始,在AMS(ActivityManagerService)与ASS(ActivityStackSupervisor)之间添加了一个ActivityStarter, 负责管理Activity的启动。

ActivityStackSupervisor#realStartActivityLocked

参考

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,544评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,430评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,764评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,193评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,216评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,182评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,063评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,917评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,329评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,543评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,722评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,425评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,019评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,671评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,825评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,729评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,614评论 2 353