Android5.0 Activty启动流程源码分析

本文出自门心叼龙的博客,属于原创类容,转载请注明出处。

看了标题很多人可能会说Android10都出来了,为什么你还要写一篇Android5.0中Activity的启动流程,我们知道Android 5.0是Google于2014 年 10 月分发布的,而上上个月也就是9分月Android10正式发布了,这样一看确实有些不合适,其实我本来是要写Android10的,因为我打算写一个系列的源码分析,为了知识的完整性以及新旧版本之前有一个明显的对比,遵循知识学习的循序渐进的特点,因此还是从Android5.0的Activity的启动流程说起,然后在分析Android10.0的启动流程,Android系统经过这么多年的发展已经迭代了十几个版本,5.0在各个版本中有着举足轻重的江湖地位。

这是Android5.0的ActivityThread的类继承关系图:


在这里插入图片描述

下面我在看看Android10.0中ActivityThread的类继承关系图:


在这里插入图片描述

很明显ActivityThread作为Activity启动的核心功能类从5.0到10.0已经发生了很大的变化,ActivityThread多了一层继承ClientTransactionHandler,而且代码量由5.0的5000多行到10.0的7000多行,增加了2000多行的源码,我们很有必要搞清楚这里面到底发生了什么变化,虽然我们日常在应用层开发过程并不需要关心这些问题,但是源码分析作为成为高级工程师成长的必经之路,Android操作系统作为众多类Linux系统中的杰出代表,我们研究Activity底层的启动流程就是在研究Android操作系统,通过对Android操作系统的学习有助于提供我们对整个Android操作系统技术实现的理解,从而来提升我们的内功修炼。Android系统的内部实现大多数都是非常复杂的,我们研究内部实现上更注重于整体流程的把握,否则深入代码细节而无法自拔。

Acitivity中的流程

Activity作为四大组件之首,它是整个应用程序的门面,负责应用程序中数据的展示,是用户和应用程序之间交互的接口。 我们通过调用Activity的startActivity方法就可以启动一个Activity,启动之后我们的界面就展现在我们的面前了,这个操作是我们学习Android开发的时候第一堂课都应该掌握的知识,我们有没有思考过这样一个问题:Activity的实例对象是在什么时候创建的?Activity的onCreate方法是在什么时候回调的?那么通过这篇的学习这些疑问将一一拨云见日。
首先我们通过startActivity方法启动一个Activity,代码如下:

 public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        startActivity(new Intent(this,SecondActivity.class));
    }
}

很简单,通过Intent将要启动的SecondActivity包装起来,然后把Intent作为startActivity方法的参数并调用它,此时一个Activity就打开了,进入该方法查看它的代码实现,startActivity(Intent intent)方法很简单就一行代码startActivity(intent, null),

 @Override
    public void startActivity(Intent intent) {
        this.startActivity(intent, null);
    }

我们继续往下走:

 @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(Intent intent, int requestCode, @Nullable Bundle options) {
        if (mParent == null) {
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
            if (ar != null) {
                mMainThread.sendActivityResult(
                    mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                    ar.getResultData());
            }
            if (requestCode >= 0) {
                // If this start is requesting a result, we can avoid making
                // the activity visible until the result is received.  Setting
                // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
                // activity hidden during this time, to avoid flickering.
                // This can only be done when a result is requested because
                // that guarantees we will get information back when the
                // activity is finished, no matter what happens to it.
                mStartedActivity = true;
            }

            final View decor = mWindow != null ? mWindow.peekDecorView() : null;
            if (decor != null) {
                decor.cancelPendingInputEvents();
            }
            // TODO Consider clearing/flushing other event sources and events for child windows.
        } else {
            if (options != null) {
                mParent.startActivityFromChild(this, intent, requestCode, options);
            } else {
                // Note we want to go through this method for compatibility with
                // existing applications that may have overridden it.
                mParent.startActivityFromChild(this, intent, requestCode);
            }
        }
        if (options != null && !isTopOfTask()) {
            mActivityTransitionState.startExitOutTransition(this, options);
        }
    }

Instrmentation的流程

每个Activity内部都有一个该Instrumentation对象的引用,该类主要用于调用AMS以及统计、测量该应用程序的所有开销,包括Activity的创建,Application的创建,Activity的onCreate方法的执行都是在由它完成的。很明显从上面代码的第4行Instrmentation.execStartActivity才是整个方法的核心代码,从此启动流程由Activity转移到了Instrmentation,具体execStartActivity方法的代码实现如下:

 public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        if (mActivityMonitors != null) {
            synchronized (mSync) {
                final int N = mActivityMonitors.size();
                for (int i=0; i<N; i++) {
                    final ActivityMonitor am = mActivityMonitors.get(i);
                    if (am.match(who, null, intent)) {
                        am.mHits++;
                        if (am.isBlocking()) {
                            return requestCode >= 0 ? am.getResult() : null;
                        }
                        break;
                    }
                }
            }
        }
        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) {
        }
        return null;
    }

从以上的代码可以看出启动Activity的工作在Instrmentation类中已经一个execStartActivity方法的短暂停留,就到了ActivityManagerNative.getDefault()的startActivity方法,ActivityManagerNative的继承关系如下:

public abstract class ActivityManagerNative extends Binder implements IActivityManager
{
    /**
     * Cast a Binder object into an activity manager interface, generating
     * a proxy if needed.
     */
    static public IActivityManager asInterface(IBinder obj) {
        if (obj == null) {
            return null;
        }

它其实是一个抽象类继承了Binder并实现了IActivityManag接口,下面是ActivityManagerService 的继承关系:

public final class ActivityManagerService extends ActivityManagerNative
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {

    private static final String USER_DATA_DIR = "/data/user/";
    // File that stores last updated system version and called preboot receivers
    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";

通以上的两段小代码我们不难发现:ActivityManagerService 继承了ActivityManagerNative,也就是说ActivityManagerNative.getDefault的startActivity方法的实际上是由他的实现类ActivityManagerService的startActivity来完成的,因此接下来的流程就由Instrumentation流转到ActivityManagerService 了,此时进行了跨进程调用,由于本文主要是讲Acitivity的启动流程,对Binder跨进行调用不了解的可以自行查阅相关资料。

ActivityManagerService的流程

ActivityManagerService是Android系统中最核心的服务,主要负责系统中四大组件的启动、切换、调度及应用进程的管理和调度等工作,该类还是相当庞大的将近2万的代码量,有着琳琅满目的数据对象,稍不注意,就给迷失了方向。

  • Activity管理:统一调度Activity的启动和关闭,Activity的启动和关闭都是由AMS发出的命令,具体的完成是由Activity自己来完成的
  • 内存管理:内存不够用的时候回干掉Activity
  • 进程管理:通过AMS可以查询当前正在运行进程的信息

AMS中的一些总要的数据对象:进程数据类 ProcessRecord,Activity数据类 ActivityRecord,任务栈数据类TaskRecord类它确保Activity启动、退出的顺序

接着我们来看ActivityManagerService的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 options) {
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
            resultWho, requestCode, startFlags, profilerInfo, options,
            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 options, int userId) {
        enforceNotIsolatedCaller("startActivity");
        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
                false, ALLOW_FULL_ONLY, "startActivity", null);
        // 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, userId, null, null);
    }

代码也不长,很明显在ActivityManagerService类经过两个方法的调用,就到了StackSupervisor的startActivityMayWait方法。此时的流程都是在后台服务进程中进行的。

ActivityStackSupervisor流程

现在我们的流程由ActivityManagerService走到了ActivityStackSupervisor的startActivityMayWait方法里面,我们看下他的代码实现:

 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, int userId, IActivityContainer iContainer, TaskRecord inTask) {
        // Refuse possible leaked file descriptors
        if (intent != null && intent.hasFileDescriptors()) {
            throw new IllegalArgumentException("File descriptors passed in Intent");
        }
        boolean componentSpecified = intent.getComponent() != null;

        // Don't modify the client's object!
        intent = new Intent(intent);

        // Collect information about the target of the Intent.
        ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags,
                profilerInfo, userId);

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

            Binder.restoreCallingIdentity(origId);

            if (stack.mConfigWillChange) {

startActivityMayWait方法一共有900多行,处理过程中会调用它的startActivityLocked方法,startActivityLocked方法的1490行会调用startActivityUncheckedLocked,代码如下:

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 componentSpecified, ActivityRecord[] outActivity, ActivityContainer container,
            TaskRecord inTask) {
        int err = ActivityManager.START_SUCCESS;

        ProcessRecord callerApp = null;
        doPendingActivityLaunchesLocked(false);

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

        if (err < 0) {
            // If someone asked to have the keyguard dismissed on the next
            // activity start, but we are not actually doing an activity
            // switch...  just dismiss the keyguard now, because we
            // probably want to see whatever is behind it.
            notifyActivityDrawnForKeyguard();
        }
        return err;
    }
final int startActivityUncheckedLocked(ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags,
            boolean doResume, Bundle options, TaskRecord inTask) {
        final Intent intent = r.intent;
        final int callingUid = r.launchedFromUid;
                    if (!addingToTask && reuseTask == null) {
                        // We didn't do anything...  but it was needed (a.k.a., client
                        // don't use that intent!)  And for paranoia, make
                        // sure we have correctly resumed the top activity.
                        if (doResume) {
                            targetStack.resumeTopActivityLocked(null, options);
                        } else {
                            ActivityOptions.abort(options);
                        }
                        return ActivityManager.START_TASK_TO_FRONT;
                    }

这两个方法的代码有很长,没有把源代码完全的贴出来:startActivityLocked方法的最后会调用startActivityUncheckedLocked方法,这个方法的1957会最终会调用ActivityStack的resumeTopActivityLocked方法,从此整个启动流程由ActivityStackSupervisor里面经过三个方法的调用就到了ActivityStack的resumeTopActivityLocked方法。

ActivityStack的流程

ActivityStack的resumeTopActivityLocked方法的代码实现如下:

  final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
        if (inResumeTopActivity) {
            // Don't even start recursing.
            return false;
        }

        boolean result = false;
        try {
            // Protect against recursion.
            inResumeTopActivity = true;
            result = resumeTopActivityInnerLocked(prev, options);
        } finally {
            inResumeTopActivity = false;
        }
        return result;
    }

紧接着resumeTopActivityLocked又会调用它自身的resumeTopActivityInnerLocked方法

final boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {
        if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen("");
           // Whoops, need to restart this activity!
            if (!next.hasBeenLaunched) {
                next.hasBeenLaunched = true;
            } else {
                if (SHOW_APP_STARTING_PREVIEW) {
                    mWindowManager.setAppStartingWindow(
                            next.appToken, next.packageName, next.theme,
                            mService.compatibilityInfoForPackageLocked(
                                    next.info.applicationInfo),
                            next.nonLocalizedLabel,
                            next.labelRes, next.icon, next.logo, next.windowFlags,
                            null, true);
                }
                if (DEBUG_SWITCH) Slog.v(TAG, "Restarting: " + next);
            }
            if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Restarting " + next);
            mStackSupervisor.startSpecificActivityLocked(next, true, true);
        }
        return true;
    }

resumeTopActivityInnerLocked方法太长,我们只看的关键部分mStackSupervisor.startSpecificActivityLocked(next, true, true)这一行,此时逻辑再次回到了ActivityStackSupervisor的startSpecificActivityLocked方法。

再次回到了ActivityStackSupervisor的流程

 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 {
                if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                        || !"android".equals(r.info.packageName)) {
                    // Don't add this if it is a platform component that is marked
                    // to run in multiple processes, because this is actually
                    // part of the framework so doesn't make sense to track as a
                    // separate apk in the process.
                    app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
                            mService.mProcessStats);
                }
                realStartActivityLocked(r, app, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting activity "
                        + r.intent.getComponent().flattenToShortString(), e);
            }

            // If a dead object exception was thrown -- fall through to
            // restart the application.
        }

        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
    }
    ```
    截止目前在我们在ActivityStackSupervisor类中看到Activity启动的核心方法realStartActivityLocked,代码如下:
    ```java
     final boolean realStartActivityLocked(ActivityRecord r,
            ProcessRecord app, boolean andResume, boolean checkConfig)
            throws RemoteException {

        r.startFreezingScreenLocked(app, 0);
        if (false) Slog.d(TAG, "realStartActivity: setting app visibility true");
        mWindowManager.setAppVisibility(r.appToken, true);

        // schedule launch ticks to collect information about slow apps.
        r.startLaunchTickingLocked();

        // Have the window manager re-evaluate the orientation of
        // the screen based on the new activity order.  Note that
        // as a result of this, it can call back into the activity
        // manager with a new orientation.  We don't care about that,
        // because the activity is not currently running so we are
        // just restarting it anyway.
        if (checkConfig) {
            Configuration config = mWindowManager.updateOrientationFromAppTokens(
                    mService.mConfiguration,
                    r.mayFreezeScreenLocked(app) ? r.appToken : null);
            mService.updateConfigurationLocked(config, r, false, false);
        }

        r.app = app;
        app.waitingToKill = null;
        r.launchCount++;
        r.lastLaunchTime = SystemClock.uptimeMillis();

        if (localLOGV) Slog.v(TAG, "Launching: " + r);

        int idx = app.activities.indexOf(r);
        if (idx < 0) {
            app.activities.add(r);
        }
        mService.updateLruProcessLocked(app, true, null);
        mService.updateOomAdjLocked();

        final ActivityStack stack = r.task.stack;
        try {
            if (app.thread == null) {
                throw new RemoteException();
            }
            List<ResultInfo> results = null;
            List<Intent> newIntents = null;
            if (andResume) {
                results = r.results;
                newIntents = r.newIntents;
            }
            if (DEBUG_SWITCH) Slog.v(TAG, "Launching: " + r
                    + " icicle=" + r.icicle
                    + " with results=" + results + " newIntents=" + newIntents
                    + " andResume=" + andResume);
            if (andResume) {
                EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY,
                        r.userId, System.identityHashCode(r),
                        r.task.taskId, r.shortComponentName);
            }
            if (r.isHomeActivity() && r.isNotResolverActivity()) {
                // Home process is the root process of the task.
                mService.mHomeProcess = r.task.mActivities.get(0).app;
            }
            mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
            r.sleeping = false;
            r.forceNewConfig = false;
            mService.showAskCompatModeDialogLocked(r);
            r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
            String profileFile = null;
            ParcelFileDescriptor profileFd = null;
            if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {
                if (mService.mProfileProc == null || mService.mProfileProc == app) {
                    mService.mProfileProc = app;
                    profileFile = mService.mProfileFile;
                    profileFd = mService.mProfileFd;
                }
            }
            app.hasShownUi = true;
            app.pendingUiClean = true;
            if (profileFd != null) {
                try {
                    profileFd = profileFd.dup();
                } catch (IOException e) {
                    if (profileFd != null) {
                        try {
                            profileFd.close();
                        } catch (IOException o) {
                        }
                        profileFd = null;
                    }
                }
            }

            ProfilerInfo profilerInfo = profileFile != null
                    ? new ProfilerInfo(profileFile, profileFd, mService.mSamplingInterval,
                    mService.mAutoStopProfiler) : null;
            app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP);
            app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                    System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
                    r.compat, r.task.voiceInteractor, app.repProcState, r.icicle, r.persistentState,
                    results, newIntents, !andResume, mService.isNextTransitionForward(),
                    profilerInfo);

最终该方法调用了 app.thread.scheduleLaunchActivity的方法,很明显流程由ActivityStackSupervisor到了ApplicationThread的scheduleLaunchActivity方法,其中ApplicationThread是ActivityThread内部类,ApplicationThread的继承关系如下:

private class ApplicationThread extends ApplicationThreadNative {
        private static final String ONE_COUNT_COLUMN = "%21s %8d";
        private static final String TWO_COUNT_COLUMNS = "%21s %8d %21s %8d";
        private static final String DB_INFO_FORMAT = "  %8s %8s %14s %14s  %s";

        private int mLastProcessState = -1;

        private void updatePendingConfiguration(Configuration config) {
            synchronized (mResourcesManager) {
                if (mPendingConfiguration == null ||
                        mPendingConfiguration.isOtherSeqNewer(config)) {
                    mPendingConfiguration = config;
                }
            }
        }

ApplicationThreadNative 的继承关系如下:

/** {@hide} */
public abstract class ApplicationThreadNative extends Binder
        implements IApplicationThread {
    /**
     * Cast a Binder object into an application thread interface, generating
     * a proxy if needed.
     */
    static public IApplicationThread asInterface(IBinder obj) {
        if (obj == null) {
            return null;
        }
        IApplicationThread in =
            (IApplicationThread)obj.queryLocalInterface(descriptor);
        if (in != null) {
            return in;
        }        
        return new ApplicationThreadProxy(obj);
    }

从上面的两端代码我们不难发现ApplicationThread其本质也是一个Binder,即可实现跨进程通信,同时该类是ActivityThread的一个内部类,主要用于接受从AMS传递过来的消息,继而做相应处理。那么随着ActivityStackSupervisor类的realStartActivityLocked方法对app.thread.scheduleLaunchActivity的调用,Activity的启动流程由后台服务进程进入到了前台进程。

ActivityThread的流程

ActivityThread该类为应用程序所对应进程的主线程类,即我们通常所说的UI线程。一个ActivityThread类对应于一个进程。最重要的是,每个应用程序的入口是该类中的static main()函数 。
下面我们看下 ApplicationThread的scheduleLaunchActivity方法实现:

public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
              ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
              IVoiceInteractor voiceInteractor, int procState, Bundle state,
              PersistableBundle persistentState, List<ResultInfo> pendingResults,
              List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
              ProfilerInfo profilerInfo) {

          updateProcessState(procState, false);

          ActivityClientRecord r = new ActivityClientRecord();

          r.token = token;
          r.ident = ident;
          r.intent = intent;
          r.voiceInteractor = voiceInteractor;
          r.activityInfo = info;
          r.compatInfo = compatInfo;
          r.state = state;
          r.persistentState = persistentState;

          r.pendingResults = pendingResults;
          r.pendingIntents = pendingNewIntents;

          r.startsNotResumed = notResumed;
          r.isForward = isForward;

          r.profilerInfo = profilerInfo;

          updatePendingConfiguration(curConfig);

          sendMessage(H.LAUNCH_ACTIVITY, r);
      }

以上代码很简单最后就通过Handler发了一个LAUNCH_ACTIVITY的消息,ActivityThread的Handler收到消息后就到了ActivityThread的handleLaunchActivity方法:

 private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
       // If we are getting ready to gc after going to the background, well
       // we are back active so skip it.
       unscheduleGcIdler();
       mSomeActivitiesChanged = true;

       if (r.profilerInfo != null) {
           mProfiler.setProfiler(r.profilerInfo);
           mProfiler.startProfiling();
       }

       // Make sure we are running with the most recent config.
       handleConfigurationChanged(null, null);

       if (localLOGV) Slog.v(
           TAG, "Handling launch of " + r);

       Activity a = performLaunchActivity(r, customIntent);

       if (a != null) {
           r.createdConfig = new Configuration(mConfiguration);
           Bundle oldState = r.state;
           handleResumeActivity(r.token, false, r.isForward,
                   !r.activity.mFinished && !r.startsNotResumed);

           if (!r.activity.mFinished && r.startsNotResumed) {
               // The activity manager actually wants this one to start out
               // paused, because it needs to be visible but isn't in the
               // foreground.  We accomplish this by going through the
               // normal startup (because activities expect to go through
               // onResume() the first time they run, before their window
               // is displayed), and then pausing it.  However, in this case
               // we do -not- need to do the full pause cycle (of freezing
               // and such) because the activity manager assumes it can just
               // retain the current state it has.
               try {
                   r.activity.mCalled = false;
                   mInstrumentation.callActivityOnPause(r.activity);
                   // We need to keep around the original state, in case
                   // we need to be created again.  But we only do this
                   // for pre-Honeycomb apps, which always save their state
                   // when pausing, so we can not have them save their state
                   // when restarting from a paused state.  For HC and later,
                   // we want to (and can) let the state be saved as the normal
                   // part of stopping the activity.
                   if (r.isPreHoneycomb()) {
                       r.state = oldState;
                   }
                   if (!r.activity.mCalled) {
                       throw new SuperNotCalledException(
                           "Activity " + r.intent.getComponent().toShortString() +
                           " did not call through to super.onPause()");
                   }

               } catch (SuperNotCalledException e) {
                   throw e;

               } catch (Exception e) {
                   if (!mInstrumentation.onException(r.activity, e)) {
                       throw new RuntimeException(
                               "Unable to pause activity "
                               + r.intent.getComponent().toShortString()
                               + ": " + e.toString(), e);
                   }
               }
               r.paused = true;
           }
       } else {
           // If there was an error, for any reason, tell the activity
           // manager to stop us.
           try {
               ActivityManagerNative.getDefault()
                   .finishActivity(r.token, Activity.RESULT_CANCELED, null, false);
           } catch (RemoteException ex) {
               // Ignore
           }
       }
   }

紧接着会调用 performLaunchActivity(r, customIntent)方法

 private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");

        ActivityInfo aInfo = r.activityInfo;
        if (r.packageInfo == null) {
            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                    Context.CONTEXT_INCLUDE_CODE);
        }

        ComponentName component = r.intent.getComponent();
        if (component == null) {
            component = r.intent.resolveActivity(
                mInitialApplication.getPackageManager());
            r.intent.setComponent(component);
        }

        if (r.activityInfo.targetActivity != null) {
            component = new ComponentName(r.activityInfo.packageName,
                    r.activityInfo.targetActivity);
        }

        Activity activity = null;
        try {
            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            StrictMode.incrementExpectedActivityCount(activity.getClass());
            r.intent.setExtrasClassLoader(cl);
            r.intent.prepareToEnterProcess();
            if (r.state != null) {
                r.state.setClassLoader(cl);
            }
        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to instantiate activity " + component
                    + ": " + e.toString(), e);
            }
        }

        try {
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);

            if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
            if (localLOGV) Slog.v(
                    TAG, r + ": app=" + app
                    + ", appName=" + app.getPackageName()
                    + ", pkg=" + r.packageInfo.getPackageName()
                    + ", comp=" + r.intent.getComponent().toShortString()
                    + ", dir=" + r.packageInfo.getAppDir());

            if (activity != null) {
                Context appContext = createBaseContextForActivity(r, activity);
                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
                Configuration config = new Configuration(mCompatConfiguration);
                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
                        + r.activityInfo.name + " with config " + config);
                activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.voiceInteractor);

                if (customIntent != null) {
                    activity.mIntent = customIntent;
                }
                r.lastNonConfigurationInstances = null;
                activity.mStartedActivity = false;
                int theme = r.activityInfo.getThemeResource();
                if (theme != 0) {
                    activity.setTheme(theme);
                }

                activity.mCalled = false;
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
                if (!activity.mCalled) {
                    throw new SuperNotCalledException(
                        "Activity " + r.intent.getComponent().toShortString() +
                        " did not call through to super.onCreate()");
                }
                r.activity = activity;
                r.stopped = true;
                if (!r.activity.mFinished) {
                    activity.performStart();
                    r.stopped = false;
                }
                if (!r.activity.mFinished) {
                    if (r.isPersistable()) {
                        if (r.state != null || r.persistentState != null) {
                            mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
                                    r.persistentState);
                        }
                    } else if (r.state != null) {
                        mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
                    }
                }
                if (!r.activity.mFinished) {
                    activity.mCalled = false;
                    if (r.isPersistable()) {
                        mInstrumentation.callActivityOnPostCreate(activity, r.state,
                                r.persistentState);
                    } else {
                        mInstrumentation.callActivityOnPostCreate(activity, r.state);
                    }
                    if (!activity.mCalled) {
                        throw new SuperNotCalledException(
                            "Activity " + r.intent.getComponent().toShortString() +
                            " did not call through to super.onPostCreate()");
                    }
                }
            }
            r.paused = true;

            mActivities.put(r.token, r);

        } catch (SuperNotCalledException e) {
            throw e;

        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to start activity " + component
                    + ": " + e.toString(), e);
            }
        }

        return activity;
    }

该方法主要做了一下几个工作:

    1. Activity的创建:Activity activity = mInstrumentation.newActivity创建
    1. Application的创建: app = r.packageInfo.makeApplication(false, mInstrumentation);
    1. Activity的onCreate方法的执行:mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState)

接着我们看Instrumentation的callActivityOnCreate方法

 public void callActivityOnCreate(Activity activity, Bundle icicle,
            PersistableBundle persistentState) {
        prePerformCreate(activity);
        activity.performCreate(icicle, persistentState);
        postPerformCreate(activity);
    }

Activity的回归流程

然后activity.performCreate方法执行了

final void performCreate(Bundle icicle, PersistableBundle persistentState) {
        onCreate(icicle, persistentState);
        mActivityTransitionState.readState(icicle);
        performCreateCommon();
    }
public void onCreate(@Nullable Bundle savedInstanceState,
            @Nullable PersistableBundle persistentState) {
        onCreate(savedInstanceState);
}

紧接着performCreate方法内部又会调用它的onCreate方法,至此整个Activity的启动流程就走完了,最终由它的startActivity方法开始,onCreate方法结束。

总结

从上面的流程来看Activity的启动过程是非常复杂的,所涉及到的类是非常多的,下面我画了一张方法调用流程图,帮助大家来理解Activity的启动过程。


在这里插入图片描述

Activity、ActivityThread、Instrementation之间的关系

我们将我们应用程序比作一个公司,那么Activity对应于公司的每一个员工,ActivithThread对应于公司的董事长管理所有人,Instrumentation对应于这个公司的董事长秘书,大小事都需要他操心受气的命,接受来自人(Activity/ActivithThread)的命令 ,去单向调用ActivityManagerService。

ActivityManagerService,ActivityStackSupervisor,ActivityStack之间的关系

ActivityManagerService是Android中最核心的服务,主要负责系统中四大组件的启动、切换、调度及应用进程的管理和调度等工作,ActivityManagerService中ActivityStackSupervisor和ActivityStack对象的调用链经常切来换去的,非常的绕。

ActivityStack从名字上看他就是Activity栈,内部维护了一个ArrayList<TaskRecord>,用来管理TaskRecord,另外,ActivityStack中还持有ActivityStackSupervisor对象,这个是用来管理ActivityStacks的。ActivityStack是由ActivityStackSupervisor来创建的,实际ActivityStackSupervisor就是用来管理ActivityStack的,继续看下面的ActivityStackSupervisor分析。

ActivityStackSupervisor,顾名思义,就是用来管理ActivityStack的。ActivityStackSupervisor内部有两个不同的ActivityStack对象:mHomeStack、mFocusedStack,用来管理不同的任务。ActivityStackSupervisor内部包含了创建ActivityStack对象的方法。AMS初始化时会创建一个ActivityStackSupervisor对象。

ActivityManagerService与ActivityThread之间的通信

通过上面的Activity启动的代码追踪过程,我们知道,在整个过程中存在着进程间的通信,引起调用AMS的对象通常有Context 、 Instrumentation、ActivityThread等,当AMS接受到来自某个应用程序传来的消息后,在AMS内部处理完毕后,会通过Binder机制回调回该应用程序,所在ApplicationThread服务端类,即ActivityThread.java类。当ActivityThread接受到AMS传递过来的消息后,进行内部处理。如果需要的话,会继续与AMS通信。最后当整个通信完成时,ActivityThread会选择合适的对象,例如Service、Activity、BroadcastReceiver等去做相应的处理。
最后我画了一幅他们之间的通信流程图,帮助大家理解客户端和服务端的通信流程:


在这里插入图片描述

问题反馈

在使用学习中有任何问题,请留言,或加入Android、Java开发技术交流群

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