源码分析:startActivity流程

2018-09-18  本文已影响49人  一线游骑兵
先来一张时序图:
startActivity时序图.png
开始看源码

无论是Context的startActivity或者Activity的startActivity最终都调用了Activity中的startActivity:

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

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);
            ...
            }          
        } else {
          ...
        }
    }

startActivityForResult调用了Instrumentation中的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;
        try {
            ...
            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;
    }

调用了ActivityManger.getService().startActivity ,getService返回的是系统进程中的AMS在app进程中的binder代理:

    /**
     * @hide
     */
    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的内容是一个activity字符串

   public static final String ACTIVITY_SERVICE = "activity";

看到IBinder可以联想到是调用了服务进程中的方法。上边的代码是在api 26版本上,在低版本的源码中的Instrumentation中的execStartActivity方法是这样的:

  int result = ActivityManagerNative.getDefault()
               .startActivityAsUser(whoThread, who.getBasePackageName(), intent,
                       intent.resolveTypeIfNeeded(who.getContentResolver()),
                       token, target != null ? target.mEmbeddedID : null,
               requestCode, 0, null, options, user.getIdentifier());
  checkStartActivityResult(result, intent);

getDefault返回的也是IActivityManager,app持有的与AMS系统进程进行通信的binder代理:

    /**
     * Retrieve the system's default/global activity manager.
     */
    static public IActivityManager getDefault() {
        return gDefault.get();
    }

    private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            IBinder b = ServiceManager.getService("activity");
            if (false) {
                Log.v("ActivityManager", "default service binder = " + b);
            }
            IActivityManager am = asInterface(b);
            if (false) {
                Log.v("ActivityManager", "default service = " + am);
            }
            return am;
        }
    };

可以看到,高低版本都是通过 IBinder b = ServiceManager.getService("activity");来获取服务端的AMS的IBinder对象,通过得到的binder来生成IActivityManager,客户端(app)通过这个IActivityManager来和服务端进程(AMS)通信。
继续回到startActivity的流程上,我们按照高版本代码来看,ActivityManager.getService().startActivity最终调用的是系统进程中的ActivityManagerService中的方法:

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

调用自身的startActivityAsUser:

    @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) {
        enforceNotIsolatedCaller("startActivity");
        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
        // 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,
                "startActivityAsUser");
    }

最终调用的是ActivityStarter中的方法【ActivityStarter也是运行在系统进程中】,该方法主要是解析intent中的内容。继续往下进入startActivityMayWait:

            final ActivityRecord[] outRecord = new ActivityRecord[1];
            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, reason);

          ...

ActivityStarter.startActivityLocked:

    int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
            String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
            String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
            ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
            ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container,
            TaskRecord inTask, String reason) {

     
        mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
                aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
                callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
                container, inTask);

        return mLastStartActivityResult;
    }

在ActivityStarter.startActivity中的主要操作做了根据intent中的启动类型时将该进程app的Activity栈帧,以及权限校验等处理,代码较多,只贴关键的一部分

return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true,
                options, inTask, outActivity);

在处理完栈帧后,又调用了自身的该重载方法:startActivity

mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
                mOptions);

在该方法中调用了自身的startActivityLocked方法,该方法代码很长,只关注核心代码:

    // Note: This method should only be called from {@link startActivity}.
    private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {
    ...
        mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
                mOptions);
        ...
    }

在该方法中,又调用了自身的 startActivityLocked方法:

    int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
            String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
            String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
            ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
            ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container,
            TaskRecord inTask, String reason) {  
        ...

        mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
                aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
                callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
                container, inTask);

        return mLastStartActivityResult;
    }

令人迷惑的是,在该方法中,又调用了自己的startActivity方法,我在这个循环上绕了好几圈。猜测刚刚开启一个Activity没有经过一系列检查验证,因此走了unCheck方法,之后校验完对该Activity进行locked,之后再次start,再次走一遍startActivity-->startActivity【前边说有2个Activity】,反反复复的看,结合网上的文章,猜测可能走到了这个判断里边:

        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.getTask());
            topStack.mLastPausedActivity = null;
            if (mDoResume) {
                mSupervisor.resumeFocusedStackTopActivityLocked();
            }
            ActivityOptions.abort(mOptions);
            if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
                return START_RETURN_INTENT_TO_CALLER;
            }
            top.deliverNewIntentLocked(
                    mCallingUid, mStartActivity.intent, mStartActivity.launchedFromPackage);

            mSupervisor.handleNonResizableTaskIfNeeded(top.getTask(), preferredLaunchStackId,
                    preferredLaunchDisplayId, topStack.mStackId);

            return START_DELIVERED_TO_TOP;
        }

在第二个startActivity方法中,有很多if+return语句,我们暂时不管之前的第一遍的两次+unCheck+locked方法具体做了什么,总之现在应该是正常的,而且已经启动了的,即dontStart=true,第一次循环应该没有走到true,加工之后再次回来就说明已经start过了,而且结合代码字面意思,下一步应该是走onResume方法了。
mSupervisor.resumeFocusedStackTopActivityLocked();方法名中猜测,可能要对栈顶已经locked的Activity方法进行resume处理,点击进入继续追踪:
进入到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);
        }
        final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
        if (r == null || r.state != RESUMED) {
            mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
        } else if (r.state == RESUMED) {
            // Kick off any lingering app transitions form the MoveTaskToFront operation.
            mFocusedStack.executeAppTransition(targetOptions);
        }
        return false;
    }

这下尴尬了,在下边的方法里有多个分支,并且每个分支里边的方法看似差不多,那我们根据上边的方法中的参数可以知道,三个参数均为空,因此第一个if肯定进不去,肯定进入中间的方法:mFocusedStack.resumeTopActivityUncheckedLocked(null, null);,因此现在又跳到了ActivityStack.resumeTopActivityUncheckedLocked()方法:

    boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
        if (mStackSupervisor.inResumeTopActivity) {
            // Don't even start recursing.
            return false;
        }
        boolean result = false;
        try {
            mStackSupervisor.inResumeTopActivity = true;
            result = resumeTopActivityInnerLocked(prev, options);
        } finally {
            mStackSupervisor.inResumeTopActivity = false;
        }   
        mStackSupervisor.checkReadyForSleepLocked();
        return result;
    }

点击进入resumeTopActivityInnerLocked方法中,

    private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
        ...

        final boolean resumeWhilePausing = (next.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0
                && !lastResumedCanPip;

        boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, false);
        if (mResumedActivity != null) {            
            pausing |= startPausingLocked(userLeaving, false, next, false);
        }   

        ActivityStack lastStack = mStackSupervisor.getLastStack();
        if (next.app != null && next.app.thread != null) {
            boolean notUpdated = true;
            if (notUpdated) {
                ActivityRecord nextNext = topRunningActivityLocked();
                if (nextNext != next) {
                    // Do over!
                    mStackSupervisor.scheduleResumeTopActivities();
                }
                if (!next.visible || next.stopped) {
                    next.setVisibility(true);
                }
                next.completeResumeLocked();
                if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
                return true;
            }
        }
        return true;
    }

代码很多,有400多行,主要操作如下:

  1. 调用了第一个Activity的pause操作
  2. 调用了新的Activity的resume操作。

其他处理:

  1. 处理了切换Activity的动画
  2. 处理了透明activity的情况
  3. 更新一下LRU进程列表【启动新的应用时 】
  4. 提交pendingIntent
  5. 处理可能存在的newIntent回调
  6. 清除各种flag

先来追踪一下startPausingLocked方法:
ActivityStack.startPausingLocked:

 final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
            ActivityRecord resuming, boolean pauseImmediately) {
    ...
        ActivityRecord prev = mResumedActivity;
        prev.state = ActivityState.PAUSING;
       
        mPausingActivity = prev;
        mLastPausedActivity = prev;
       
        final ActivityRecord next = mStackSupervisor.topRunningActivityLocked();

        if (prev.app != null && prev.app.thread != null) {
            try {
                mService.updateUsageStats(prev, false);
                prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
                        userLeaving, prev.configChangeFlags, pauseImmediately);
            } catch (Exception e) {
                mPausingActivity = null;
                mLastPausedActivity = null;
                mLastNoHistoryActivity = null;
            }
        } else {
            mPausingActivity = null;
            mLastPausedActivity = null;
            mLastNoHistoryActivity = null;
        }
    ...
    }

通过关键代码可知该方法的主要目的:

  1. 获取到当前resumed的Activity,指定为prev.
  2. 获取到当前已经在栈顶运行中的锁定的新的Activity,指定为next,即将要启动的Activity
  3. 中间对将要pause的Activity的状态进行了操作
  4. **最重要的一步:调用prev.app.thread.schedulePauseActivity方法,prev.app的类型为 ProcessRecord app;,而app.thread的类型为: IApplicationThread thread;,到此多少有点儿明白了,IApplicationThread是服务进程持有的用来与app进程进行通信的binder代理,app进程通过ActivityMangagerNative(与系统进程的AMS一样都实现了IActivityManager.Stub接口)与位于系统进程的AMS进行通信,但是binder的通信是单向的,所以系统进程与app进程就通过这个IApplicationThread进行,在app主线程的ActivityThread类中有一个内部类ApplicationThread,上边的IApplicationThread就是该类位于系统进程中的代理,因此该方法的调用最终指向了ActivityThread中ApplicationThread内部类中的schedulePauseActivity方法

此时,AMS的任务已经完成,ApplicationThread类中的schedulePauseActivity方法如下:
首先从类的集成关系就可以验证上边的说明:

private class ApplicationThread extends IApplicationThread.Stub{}

该方法如下:

        public final void schedulePauseActivity(IBinder token, boolean finished,
                boolean userLeaving, int configChanges, boolean dontReport) {
            int seq = getLifecycleSeq();
            sendMessage(
                    finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
                    token,
                    (userLeaving ? USER_LEAVING : 0) | (dontReport ? DONT_REPORT : 0),
                    configChanges,
                    seq);
        }

sendMessage内容如下:

    private void sendMessage(int what, Object obj, int arg1, int arg2, int seq) {
        Message msg = Message.obtain();
        msg.what = what;
        SomeArgs args = SomeArgs.obtain();
        args.arg1 = obj;
        args.argi1 = arg1;
        args.argi2 = arg2;
        args.argi3 = seq;
        msg.obj = args;
        mH.sendMessage(msg);
    }

mH是app进程中main方法(ui线程启动时开启的一个消息循环)类。跳到handleMessage中对应的分支:

                case PAUSE_ACTIVITY: {
                    SomeArgs args = (SomeArgs) msg.obj;
                    handlePauseActivity((IBinder) args.arg1, false,
                            (args.argi1 & USER_LEAVING) != 0, args.argi2,
                            (args.argi1 & DONT_REPORT) != 0, args.argi3);
                } break;
                case PAUSE_ACTIVITY_FINISHING: {
                    SomeArgs args = (SomeArgs) msg.obj;
                    handlePauseActivity((IBinder) args.arg1, true, (args.argi1 & USER_LEAVING) != 0,
                            args.argi2, (args.argi1 & DONT_REPORT) != 0, args.argi3);
                } break;

这两个类型最终都都是调用的handlePauseActivity方法:

   private void handlePauseActivity(IBinder token, boolean finished,
            boolean userLeaving, int configChanges, boolean dontReport, int seq) {
        ActivityClientRecord r = mActivities.get(token);
    ...
        if (r != null) {
           
            r.activity.mConfigChangeFlags |= configChanges;
            performPauseActivity(token, finished, r.isPreHoneycomb(), "handlePauseActivity");

            ...
            mSomeActivitiesChanged = true;
        }
    }

继续看performPauseActivity方法:

   final Bundle performPauseActivity(IBinder token, boolean finished,
            boolean saveState, String reason) {
        ActivityClientRecord r = mActivities.get(token);
        return r != null ? performPauseActivity(r, finished, saveState, reason) : null;
    }

    final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
            boolean saveState, String reason) {
    ...
        performPauseActivityIfNeeded(r, reason);

    ...
        return !r.activity.mFinished && saveState ? r.state : null;
    }

    private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
        if (r.paused) {
            // You are already paused silly...
            return;
        }

        try {
            r.activity.mCalled = false;
            mInstrumentation.callActivityOnPause(r.activity);
        }catch (Exception e) {
            if (!mInstrumentation.onException(r.activity, e)) {
                throw new RuntimeException("Unable to pause activity "
                        + safeToComponentShortString(r.intent) + ": " + e.toString(), e);
            }
        }
        r.paused = true;
    }

可以看到,真正的实现最终还是落到了苦力Instrumentation身上:

    public void callActivityOnPause(Activity activity) {
        activity.performPause();
    }

直接调用的Activity中的performPause方法:

    final void performPause() {
        mDoReportFullyDrawn = false;
        mFragments.dispatchPause();
        mCalled = false;
        onPause();
        mResumed = false;
        ...
        mResumed = false;
    }

在该方法中,最终调用了暴露给用户的方法:对应的Activity声明周期的onPause()方法,此时,旧的Activity的onPause方法已经走完,接下来会继续走新的Activity的onResume方法。

旧的Activity的onPause已经执行完毕,按照已知的生命周期下面应该执行新Activity的onResume方法。
再次回到ActivityStack中的resumeTopActivityInnerLocked方法中,有这样一行代码:

 mStackSupervisor.scheduleResumeTopActivities();

点击进入StackSupervisor类中的该方法中:

    final void scheduleResumeTopActivities() {
        if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) {
            mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
        }
    }

通过mHandler发送了一个消息而已,进入handleMessage中:

                case RESUME_TOP_ACTIVITY_MSG: {
                    synchronized (mService) {
                        resumeFocusedStackTopActivityLocked();
                    }
                } break;
    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);
        }
        final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
        if (r == null || r.state != RESUMED) {
            mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
        } else if (r.state == RESUMED) {
            // Kick off any lingering app transitions form the MoveTaskToFront operation.
            mFocusedStack.executeAppTransition(targetOptions);
        }
        return false;
    }

根据第一个方法的参数,可以知道进入了中间的方法,此时又回到了ActivityStack类中:ActivityStack.resumeTopActivityUncheckedLocked(null,null):

    boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
        boolean result = false;
        try {
            mStackSupervisor.inResumeTopActivity = true;
            result = resumeTopActivityInnerLocked(prev, options);
        } finally {
            mStackSupervisor.inResumeTopActivity = false;
        }
        mStackSupervisor.checkReadyForSleepLocked();

        return result;
    }

很奇怪,又进入了resumeTopActivityInnerLocked方法中,再捋一遍代码,发现确实是漏掉了下边的方法,标出该方法中的三个关键点,再贴一遍代码:

   private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
        boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, false);
        if (mResumedActivity != null) {
            if (DEBUG_STATES) Slog.d(TAG_STATES,
                    "resumeTopActivityLocked: Pausing " + mResumedActivity);
            //关键代码 1
            pausing |= startPausingLocked(userLeaving, false, next, false);
        }
        if (next.app != null && next.app.thread != null) {
            boolean notUpdated = true;
            if (mStackSupervisor.isFocusedStack(this)) {               
                notUpdated = !mService.updateDisplayOverrideConfigurationLocked(config, next,
                        false /* deferResume */, mDisplayId);
            }
            if (notUpdated) {
                 ActivityRecord nextNext = topRunningActivityLocked();
              
                if (nextNext != next) {
                    // Do over!
                    //关键代码 2
                    mStackSupervisor.scheduleResumeTopActivities();
                }
                if (!next.visible || next.stopped) {
                    next.setVisibility(true);
                }
                next.completeResumeLocked();
                return true;
            }

            try {
                //关键代码 3                    
                next.app.thread.scheduleResumeActivity(next.appToken, next.app.repProcState,
                        mService.isNextTransitionForward(), resumeAnimOptions);
               
            } catch (Exception e) {
             
                return true;
            }
    
        }
        return true;
    }

和上边的一样,经过一圈轮回之后,所传的参数都不为空,因此会走到关键代码块3,中,第一次进入应该是只走到了关键代码2中,然后走了一遍又转到该关键3中。
代码3的过程很清晰,就是通过持有的app进程的binder代理,来通知app进程对该acitivity进行resume操作。
因此next.app.thread.scheduleResumeActivity方法最终调用的是ApplicationThread中的该方法:

        public final void scheduleResumeActivity(IBinder token, int processState,
                boolean isForward, Bundle resumeArgs) {
            int seq = getLifecycleSeq();
            updateProcessState(processState, false);
            sendMessage(H.RESUME_ACTIVITY, token, isForward ? 1 : 0, 0, seq);
        }

此处也是发送过来一个what为RESUME_ACTIVITY到主线程中的消息队列中。

                case RESUME_ACTIVITY:
                    SomeArgs args = (SomeArgs) msg.obj;
                    handleResumeActivity((IBinder) args.arg1, true, args.argi1 != 0, true,
                            args.argi3, "RESUME_ACTIVITY");
                    break;
   final void handleResumeActivity(IBinder token,
            boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {
        ActivityClientRecord r = mActivities.get(token);
        ...
        // TODO Push resumeArgs into the activity for consideration
        r = performResumeActivity(token, clearHide, reason);
        ...
    }

几百行代码处理了关于window等其他逻辑,关键代码应该是这一行,点击进入:

    public final ActivityClientRecord performResumeActivity(IBinder token,
            boolean clearHide, String reason) {
        ActivityClientRecord r = mActivities.get(token);
      
        if (r != null && !r.activity.mFinished) {
           try {
             
                r.activity.performResume();

                r.paused = false;
                r.stopped = false;
                r.state = null;
                r.persistentState = null;
            } catch (Exception e) {
            }
        }
        return r;
    }

可以看到,此处直接调用了activity.performResume方法:

     final void performResume() {
        performRestart();

        mFragments.execPendingActions()

        // mResumed is set by the instrumentation
        mInstrumentation.callActivityOnResume(this);

        mFragments.dispatchResume();

        onPostResume();
    }

在performResume方法中回调了restart方法,然后依然是将onResume的操作交给了Instrumentation,同时调用该Activity中的fragment方法,然后调用了onPostResume方法。
进入Instrumentation中的callActivityOnResume方法:
public void callActivityOnResume(Activity activity) { activity.mResumed = true; activity.onResume(); ... }
此时,就进入了app中Activity的onResume声明周期方法中。至此,Activity的启动流程分析完毕。

总结:

参考文章:
https://www.jianshu.com/p/6037f6fda285

上一篇下一篇

猜你喜欢

热点阅读