Activity启动流程

246 阅读6分钟

本编文章分析的是的Android中Activity的启动流程

Activity启动流程中使用到的类

Activity

Instrumentation

ActivityManagerService

ActivityStackSupervisor

ActivityStack

Process

下面说一个场景:

ActivityA中使用startActivity开启B页面,那么生命周期的方法是怎么执行的呢?执行的流程如下

1⃣️A执行onPause方法

2⃣️B执行onCreate方法接着执行onStart方法最后执行onResume方法

3⃣️A执行onStop方法

这时ActivityB就完全的显示在手机上面并且用户可见可操作了

那么跟据上面的场景对整个流程进行一个分析

首先我们使用startActivity方法开启B页面的时候实际上调用的是Activity中startActivityForResult的代码具体代码如下

Activity.java
public void startActivity(Intent intent) {
        this.startActivity(intent, null);
    }
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);
        }
    }
public void startActivityForResult(
            String who, Intent intent, int requestCode, @Nullable Bundle options) {
        Uri referrer = onProvideReferrer();
        if (referrer != null) {
            intent.putExtra(Intent.EXTRA_REFERRER, referrer);
        }
        Instrumentation.ActivityResult ar =
            mInstrumentation.execStartActivity(
                this, mMainThread.getApplicationThread(), mToken, who,
                intent, requestCode, options);
        if (ar != null) {
            mMainThread.sendActivityResult(
                mToken, who, requestCode,
                ar.getResultCode(), ar.getResultData());
        }
        cancelInputsAndStartExitTransition(options);
    }

从上面的代码中可以看出Activity其实就是通过一层层的调用,将开启Activity的任务交由Instrumentation这个类来实现了,其实看源码的时候可以发现我们在Activity很多操作其实都是由Instrumentation来进行的,Instrumentation相当于Activity的一个管家婆的形式吧,下面我们看看开启Activity的时候Instrumentation中又是怎么做的代码如下

Instrumentation.java
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 {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess();
            int result = ActivityManagerNative.getDefault()
                .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;
    }

上面的代码可以看到Instrumentation中使用ActivityManager开启Activity,通过ActivityManagerNative.getDefault()获取了一个AMS的代理类ActivityManagerProxy,我们使用这个代理类调用startActivity通过Binder通信的方式将开启Activity的任务传递给了AMS,当AMS接收到这个任务调度后会根据Binder通信的相关协定调用AMS中的startActiviy方法,具体代码如下

AMS.java
public final int startActivity(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
            resultWho, requestCode, startFlags, profilerInfo, options,
            UserHandle.getCallingUserId());
    }
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
        enforceNotIsolatedCaller("startActivity");
       	...
        // TODO: Switch to user app stacks here.
        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
                profilerInfo, null, null, options, false, userId, null, null);
    }

通过上面的代码可以发现最终AMS调用的mStackSupervisor中的startActivityMayWait方法,那么这个mStackSupervisor是那个类的实例,实际上它就是ActivityStackSupervisor这个类的实例,下面简单介绍一下ActivityStackSupervisor这个类,这个类是ActivityStack的管理类,它管理着整个系统所有的ActivityStack,内部有mHomeStack(这个栈中包含所有的Launcher ActivityRecord)、mFocusedStack(这个栈中存放的是当前显示在前台的ActivityRecord)、mLastFocusedStack(包好的是上一次显示在前台的ActivityRecord),实际上就是管理了所有的ActivityStack以及一些其他的Activity信息。本篇不着重考虑这个类只要知道我们开启Activity的任务会交由ActivityStackSupervisor这个类来处理就好。接着上面说的会调用到这个类中的startActivityMayWait方法那么这个方法又是怎么执行的呢,它的执行代码如下

ActivityStackSupervisor.java
final int startActivityMayWait(IApplicationThread caller, int callingUid,
            String callingPackage, Intent intent, String resolvedType,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int startFlags,
            ProfilerInfo profilerInfo, WaitResult outResult, Configuration config,
            Bundle options, boolean ignoreTargetSecurity, int userId,
            IActivityContainer iContainer, TaskRecord inTask) {
  	...
    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;
}

final int startActivityLocked(IApplicationThread caller,
            Intent intent, String resolvedType, ActivityInfo aInfo,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode,
            int callingPid, int callingUid, String callingPackage,
            int realCallingPid, int realCallingUid, int startFlags, Bundle options,
            boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
            ActivityContainer container, TaskRecord inTask) {
  ...
  err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,
                startFlags, true, options, inTask);
  ...	
  return err;
}

final int startActivityUncheckedLocked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags,
            boolean doResume, Bundle options, TaskRecord inTask) {
  ...
   targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
  ...
  return ActivityManager.STRAT_SUCESS;
} 

这个时候就调用到了ActivityStack类,需要ActivityStack去执行任务实际上这才是整个流程中最让人比较闹心的地方,因为ActivityStack与ActivityStackSupervisor在这个流程中不停的互相调用,具体流程就不上太多的代码了,想知道的小伙伴可以自己跟一下源代码,最终这个流程执行的是ActivityStack中的resumeTopActivityInnerLocked这个方法,这个方法才是最终执行onPause、onCreate等调用的源头具体代码如下

  private boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {
    ...
     // We need to start pausing the current activity so the top one
        // can be resumed...
        boolean dontWaitForPause = (next.info.flags&ActivityInfo.FLAG_RESUME_WHILE_PAUSING) != 0; ①
        boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, true, dontWaitForPause);
    ...
    mStackSupervisor.startSpecificActivityLocked(next, true, true); ②
   	...
    return true;
  }

在上面的代码中省略了很多过程代码只保留了最主要的两块代码,代码块①就是去调用我们当前Activity的onPause方法,具体的调用方式如下面代码

ActivityStackSupervisor
boolean pauseBackStacks(boolean userLeaving, boolean resuming, boolean dontWait) {
  someActivityPaused |= stack.startPausingLocked(userLeaving, false, resuming,
                            dontWait);
}
ActivityStack 
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, boolean resuming,
            boolean dontWait) {
prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
                        userLeaving, prev.configChangeFlags, dontWait);
}

通过上面的代码可以发现实际上还是通过Binder机制实现的调用,只不过这次是通过AMS回掉ApplicationThread中的方法,当我们回到ActivityThread中的ApplicationThread中跟踪schedulePauseActivity这个方法时会发现确实是这个方法调用的Activity中的onPause方法。并且这个时候我们还会发现实际上还是Instrumentation通知的Activity执行onPause方法。具体代码可以查阅源码中handlePauseActivity。那么回到上面第二个代码块这块执行的就是新的Activity的创建以及之后的相关方法的执行,具体代码如下

 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) {
                realStartActivityLocked(r, app, andResume, checkConfig);
                return
          }
        ...
        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
    }

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

通过上面的代码可以发现在startSpecificActivityLoced中获取当前的Activity所在的进程,如果进程存在那么执行realStartAcitivtyLocked方法,创建新的Activity并且执行生命周期的相关方法。如果当前进程不存在的话,就需要通过AMS创建一个新的进程供给当前这个Activity使用,同时进程创建成功之后再执行绑定Application的时候会将要开启的Activity进行创建与开启,具体执行的代码依然是realStartActivityLocked,代码执行流程如下

ActivityThread main()--->thread.attach(false)--->AMS attachApplication(mAppThread) --->attachApplicationLocked(thread, callingPid)--->mStackSupervisor.attachApplicationLocked(app)--->realStartActivityLocked。

这样整个Activity的创建流程就执行完成这个时候执行的Activity中的onCreate onStart onResume方法那么剩下最后一个前一个Activity中的onStop方法再来看一下怎么执行的,onStop方法是在可见的Activity的onResume方法之后执行的原因是因为在执行handleResumeActivity的时候在方法中执行了Looper.myQueue().addIdleHandler(new Idler());这个Idler就是最后执行前一个Activity的onStop方法的调用起始点。

文末写的有些太快内容写的没有那么详细,请大家多多关照!!