Activity 启动流程分析

以在桌面点击一个App图标冷启动为例,Activity的启动大致可以总结为如下流程:

一个应用对应一个进程或多个进程,四大组件等所有组件的运行都依附于这些进程, 所以启动一个应用时没有相应的进程存在,则会先启动一个进程,接着启动其组件。

  1. 点击桌面Launcher上点击应用图标时,会通知ActivityManagerService(后面简称AMS)启动应用的入口Activity,此时AMS会检查改应用是否已经启动;
  2. 如果该应用已经启动,那么该应该对应的进程也必然存在,此时则直接显示上次退出前打开的Activity;
  3. 如果该应用未启动,则AMS会通知Zygote进程fork这个应用的进程,然后在这个dalvik应用进程里执行ActivityThreadmain;
  4. 进程启动成功后, AMS会保存这个进程的一个代理对象ActivityThread,此后AMS会使用这个`代理对象和应用进程通信;
  5. AMS通知应用进程创建入口Activity的实例,同时执行Activity生命周期方法。
为了更好的理清楚Activity的启动流程,我们先看看和AMS管理Activity相关几个类的作用及其关系,如下图:
AMS类图.png

1 ActivityManagerService
它是管理activity的入口类,聚合了ProcessRecord对象和ActivityStack对象 ;
Android中最核心的服务,主要负责系统中四大组件的启动、切换、调度及应用程序的管理和调度等工作。
负责系统中四大组件的启动、切换、调度及应用进程的管理和调度等工作。

  1. ProcessRecord
    表示应用进程记录,每个应用进程都有对应的ProcessRecord对象

  2. ActivityStack
    该类主要管理回退栈, 单个活动栈的状态和管理。
    ActivityStack管理ActivityRecord时,将属于同一个task的ActivityRecord放在一起
    负责单个Activity栈的状态和管理。

  3. TaskRecord
    Task记录信息,一个Task可能有多个ActivityRecord,但是一个ActivityRecord只能属于一个TaskRecord
    ActivityManagerService组织回退栈时以ActivityRecord为基本单位, 但是ActivityManagerService调度ActivityRecord时以task为基本单位,
    每个ActivityRecord对象都属于某个TaskRecord,一个TaskRecord可能有多个ActivityRecord。

  4. ActivityRecord
    每次启动一个Actvity会有一个对应的ActivityRecord对象,表示Activity的一个记录

  5. ActivityInfo
    Activity的信息,比如启动模式,taskAffinity,flag信息(这些信息在AndroidManifest.xml里声明Activity时填写)

顺便介绍下启动过程中其他主要相关的类

  1. ActivityManager
    此类提供有关活动,服务和包含过程的信息和交互。
    该类提供与Activity、Service和Process相关的信息以及交互方法, 可以被看作是ActivityManagerService的辅助类。
    IActivityManager:用于与ActivityManagerService交谈的系统专用API。 提供了从应用程序返回到活动管理器的调用。

  2. ActivityStarter
    用于解释如何启动活动的控制器。此类收集用于确定如何将意图和标志转变为活动以及相关任务和堆栈的所有逻辑。

  3. ActivityStackSupervisor
    Activity栈管理。负责所有Activity栈的管理。内部管理了mHomeStack、mFocusedStack 和 mLastFocusedStack三个Activity栈。其中,mHomeStack管理的是Launcher相关的Activity栈;
    mFocusedStack管理的是当前显示在前台Activity的Activity栈;
    mLastFocusedStack管理的是上一次显示在前台Activity的Activity栈。

  4. ActivityThread
    管理应用程序进程中主线程的执行,根据ActivityManager请求调度和执行Activitys、broadcasts和其他操作。ActivityThread 运行在UI线程(主线程),App的真正入口。
    管理应用程序进程中主线程的执行,根据Activity管理者的请求调度和执行activities、broadcasts及其相关的操作。

  5. ApplicationThread
    ActivityThread内部类,IApplicationThread.aidl的具体实现,提供给ActivityManager,ActivityManager通过它告知应用程序将要做的事。
    H:继承Handler,ActivityThread内部类,是应用程序进程中主线程的消息管理类。

  6. Instrumentation
    字面意思“仪器”。官方解释:用于实现应用程序检测代码的基类。 当开启仪器运行时,该类将在任何应用程序代码之前为您实例化,从而允许您监视系统与应用程序之间的所有交互。Instrumentation实现通过AndroidManifest.xml向系统描述。

Activity的启动流程:

我画了一张详细的流程图,边看流程图边看源码可能效果更佳

activity启时序图.png

主要分为三个部分:

  1. Launcher 请求 AMS 过程;

  2. AMS 调用 ApplicationThread;

  3. ActivityThread 启动 Activity;

1. Launcher 请求 AMS 过程;

点击一个App桌面图标其实是启动这个App的入口Activity,会调用Activity的startActivity方法, 此时使用的启动模式是 Intent.FLAG_ACTIVITY_NEW_TASK, 因此该Activity会在一个新的任务栈中启动;

xref:/frameworks/base/core/java/android/app/Activity.java

@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 方法。如果是调用 startActivity(intent)启动Activity,那么requestCode参数则传入-1,表示当前Activity启动一个新的Activity后,不需要获取新的Activity返回来的数据

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 {
          ...
        }
    }
    ...
}

mParent是Activity父类,是ActivityGroup类型, 表示当前Activity的容器, API 13以后已被废弃;此时mParent==null 为 true,所以接下来会执行 mInstrumentation.execStartActivity 方法;Instrumentation 是用来监控应用程序和系统的交互;

mMainThreadActivityThread类型的对象;
ApplicationThread 继承了 IApplicationThread.Stub,使用了AIDL技术实现进程间通信。在Android 8.0之前没有使用AIDL, 手写了一套类似于AIDL的代码;
IApplicationThread 是一个AIDl接口,继承了IInterface接口;Stub是接口IApplicationThread的内部类,继承了Binder类,实现了IApplicationThread接口。因此ApplicationThread就是一个Binder对象,它重写了IApplicationThread接口的抽象方法。
源码如下:

public final class ActivityThread {
    
    final ApplicationThread mAppThread = new ApplicationThread();
    ...
    private class ApplicationThread extends IApplicationThread.Stub {
        ...
    }
}

mMainThread对象初始化在当前Activity的attach方法中, attach方法在启动Activity之前被调用,attach方法主要是注册一些接 口,给一些变量初始化值,其中就创建了PhoneWindow的实例,为创建WindowManagerImpl对象做准备。通过WindowManager可以添加,删除,更新窗口,从代码角度来说 ,增加,删除,更新操作的是View;
下面是Activity attach方法源码:

 final void attach(Context context, ActivityThread aThread,
            Instrumentation instr, IBinder token, int ident,
            Application application, Intent intent, ActivityInfo info,
            CharSequence title, Activity parent, String id,
            NonConfigurationInstances lastNonConfigurationInstances,
            Configuration config, String referrer, IVoiceInteractor voiceInteractor,
            Window window, ActivityConfigCallback activityConfigCallback) {
        attachBaseContext(context);

        mFragments.attachHost(null /*parent*/);

        mWindow = new PhoneWindow(this, window, activityConfigCallback);
        mWindow.setWindowControllerCallback(this);
        mWindow.setCallback(this);
        mWindow.setOnWindowDismissedCallback(this);
        mWindow.getLayoutInflater().setPrivateFactory(this);
        if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
            mWindow.setSoftInputMode(info.softInputMode);
        }
        if (info.uiOptions != 0) {
            mWindow.setUiOptions(info.uiOptions);
        }
        mUiThread = Thread.currentThread();

        mMainThread = aThread;
        mInstrumentation = instr;
        mToken = token;
        mIdent = ident;
        mApplication = application;
        mIntent = intent;
        mReferrer = referrer;
        mComponent = intent.getComponent();
        mActivityInfo = info;
        mTitle = title;
        mParent = parent;
        mEmbeddedID = id;
        mLastNonConfigurationInstances = lastNonConfigurationInstances;
        if (voiceInteractor != null) {
            if (lastNonConfigurationInstances != null) {
                mVoiceInteractor = lastNonConfigurationInstances.voiceInteractor;
            } else {
                mVoiceInteractor = new VoiceInteractor(voiceInteractor, this, this,
                        Looper.myLooper());
            }
        }

        mWindow.setWindowManager(
                (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
                mToken, mComponent.flattenToString(),
                (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
        if (mParent != null) {
            mWindow.setContainer(mParent.getWindow());
        }
        mWindowManager = mWindow.getWindowManager();
        mCurrentConfig = config;

        mWindow.setColorMode(info.colorMode);

        setAutofillCompatibilityEnabled(application.isAutofillCompatibilityEnabled());
        enableAutofillCompatibilityIfNeeded();
    }

接着上面activity启动流程,调用mInstrumentation.execStartActivity
xref:/frameworks/base/core/java/android/app/Instrumentation.java

public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        ...
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(who);
            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;
    }
}

这里调用了AMS的startActivity方法,那么Launcher是如何和AMS进程通信的呢, 其实通过 ActivityManager.getService()方法获取到了, 具体如何获取的看如下代码:

xref:/frameworks/base/core/java/android/app/ActivityManager.java

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;
           }
       };

IActivityManager 是一个aidl接口,里面定义了启动和停止四大组件的相关方法;该aidl接口路径为:

xref:/frameworks/base/core/java/android/app/IActivityManager.aidl

要实现进程间通信,服务端AMS就要继承IActivityManager.stub,同时实现相应方法就可以;这是8.0的做法;

Android 8.0之前是手动写了一个类似于aidl接口的方式去做的,用AMS的代理对象ActivityManagerProxy来与AMS进行进程间通信,
Android 8.0 去除了ActivityManagerNative的内部类ActivityManagerProxy,代替它的则是IActivityManager,它是AMS在本地的代理。

Singleton是一个抽象类,有一个抽象方法create()。有一个get()方法,内部通过单例模式创建T对象,调用create方法创建T对象,且只会创建一次T对象;
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
获取一个关联系统服务的Binder对象;
IActivityManager.Stub.asInterface(b) 会返回实现了 IActivityManager 接口的代理对象, 基于Binder机制,通过代理对象调用系统服务 ActivityManagerService 对应的方法;

这里调用AMS的startActivity方法后, 接下来的调用流程就会进入AMS进程,也就是system_server进程;

2. AMS 调用 ApplicationThread;

xref:/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

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

mUserController.handleIncomingUser 通过获取getCallingPid 和 userid去检查调用者的权限;
倒数第二个参数TaskRecord 类型,代表的是要启动的activity所在的栈;

xref:/frameworks/base/services/core/java/com/android/server/am/ActivityStarter.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 globalConfig, Bundle bOptions, boolean ignoreTargetSecurity, int userId,
            IActivityContainer iContainer, TaskRecord inTask, String reason) {
         ...
        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);
         ...
         return res;
     }
 }

ActivityStarter是Android 7.0新加入的类,它是加载Activity的控制类,会收集所有的逻辑来决定如何将Intent和Flags转换为Activity,并将Activity和Task以及Stack相关联;

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) {
                
        if (TextUtils.isEmpty(reason)) {//1
            throw new IllegalArgumentException("Need to specify a reason.");
        }
        mLastStartReason = reason;
        mLastStartActivityTimeMs = System.currentTimeMillis();
        mLastStartActivityRecord[0] = null;
        
        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);
        if (outActivity != null) {
            // mLastStartActivityRecord[0] is set in the call to startActivity above.
            outActivity[0] = mLastStartActivityRecord[0];
        }
        return mLastStartActivityResult;
 }
private int startActivity(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) {
   int err = ActivityManager.START_SUCCESS;
  final Bundle verificationBundle = options != null ? options.popAppVerificationBundle() : null;
  ProcessRecord callerApp = null;
  if (caller != null) {//1
      //获取Launcher进程
      callerApp = mService.getRecordForAppLocked(caller);
      if (callerApp != null) {
          //获取Launcher进程的pid和uid并赋值
          callingPid = callerApp.pid;
          callingUid = callerApp.info.uid;
      } else {
          Slog.w(TAG, "Unable to find app for caller " + caller
                + " (pid=" + callingPid + ") when starting: "
                + intent.toString());
          err = ActivityManager.START_PERMISSION_DENIED;
      }
   }
        ...
   //创建即将要启动的Activity的描述类ActivityRecord
   ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
            callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
            resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
            mSupervisor, container, options, sourceRecord); //2  
   if (outActivity != null) {
       outActivity[0] = r;
   }
   ...
   doPendingActivityLaunchesLocked(false);
   return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true,
           options, inTask, outActivity);
 }

ProcessRecord callerApp代表的是 Launcher 的 ApplicationThread,然后获取到callingUid,callingPid等信息,接着创建即将要启动的activity的bean类 ActivityRecord;

private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {
    int result = START_CANCELED;
    try {
        mService.mWindowManager.deferSurfaceLayout();
        result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                   startFlags, doResume, options, inTask, outActivity);
   } finally {
       // If we are not able to proceed, disassociate the activity from the task. Leaving an
       // activity in an incomplete state can lead to issues, such as performing operations
       // without a window container.
       if (!ActivityManager.isStartResultSuccessful(result)
               && mStartActivity.getTask() != null) {
           mStartActivity.getTask().removeActivity(mStartActivity);
       }
       mService.mWindowManager.continueSurfaceLayout();
   }

   postStartActivityProcessing(r, result, mSupervisor.getLastStack().mStackId,  mSourceRecord, mTargetStack);
   return result;
 }
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {
    ...
    if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
                && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
        newTask = true;
        //创建新的TaskRecord
       result = setTaskFromReuseOrCreateNewTask(taskToAffiliate, preferredLaunchStackId, topStack);//2
   } else if (mSourceRecord != null) {
       result = setTaskFromSourceRecord();
   } else if (mInTask != null) {
       result = setTaskFromInTask();
   } else {
       setTaskToCurrentTopOrCreateNewTask();
   }
   ...
   if (mDoResume) {
       final ActivityRecord topTaskActivity = mStartActivity.getTask().topRunningActivityLocked();
       if (!mTargetStack.isFocusable() || (topTaskActivity != null && topTaskActivity.mTaskOverlay 
                && mStartActivity != topTaskActivity)) {
           ...
       } else {
           if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) {
                mTargetStack.moveToFront("startActivityUnchecked");
           }
           mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,mOptions);
      }
   } else {
       mTargetStack.addRecentActivityLocked(mStartActivity);
   }
   ...
}

由于启动的activity 的launcherMode 为 FLAG_ACTIVITY_NEW_TASK, 所以此时会通过setTaskFromReuseOrCreateNewTask方法去为该activity创建一个任务栈,

xref:/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

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;
}

mFocusedStack类型为 ActivityStack

xref:/frameworks/base/services/core/java/com/android/server/am/ActivityStack.java

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;
       result = resumeTopActivityInnerLocked(prev, options);
   } finally {
       mStackSupervisor.inResumeTopActivity = false;
   }
   mStackSupervisor.checkReadyForSleepLocked();
   return result;
}
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
    ...
    if (mResumedActivity != null) {
        if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Pausing " + mResumedActivity);     
            pausing |= startPausingLocked(userLeaving, false, next, false);
        }
    ...    
}

此处由于当前正在显示的activity是执行了onResume方法的,所以此处的 mResumedActivity != null , 因此会执行startPausingLocked方法去pause,

 final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
             ActivityRecord resuming, boolean pauseImmediately) {
       ...          
       if (prev.app != null && prev.app.thread != null) {
           prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
                   userLeaving, prev.configChangeFlags, pauseImmediately);
       ...            
}  

这里的prev.app.thread是一个远程IApplicationThread对象,通过调用这个远程对象的schedulePauseActivity来通知Launcher进入Paused状态,另外就是此刻由于Launcher还没Pause,所以prev.finishing属性为false。

private class ApplicationThread extends IApplicationThread.Stub {
     public final void schedulePauseActivity(IBinder token, boolean finished,
                boolean userLeaving, int configChanges, boolean dontReport) {
         int seq = getLifecycleSeq();
         if (DEBUG_ORDER) Slog.d(TAG, "pauseActivity " + ActivityThread.this + " operation received seq: " + seq);
         sendMessage(
                  finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
                  token,
                  (userLeaving ? USER_LEAVING : 0) | (dontReport ? DONT_REPORT : 0),
                  configChanges,
                  seq);
       }
}
private class H extends Handler {
    public static final int LAUNCH_ACTIVITY         = 100;
    public static final int PAUSE_ACTIVITY          = 101;
    
    ...
    
    public void handleMessage(Message msg) {
        if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) {
               ...
               case PAUSE_ACTIVITY: {
                   Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
                   SomeArgs args = (SomeArgs) msg.obj;
                   handlePauseActivity((IBinder) args.arg1, false,
                           (args.argi1 & USER_LEAVING) != 0, args.argi2,
                           (args.argi1 & DONT_REPORT) != 0, args.argi3);
                   maybeSnapshot();
                   Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
              } break;
              
              ...
private void handlePauseActivity(IBinder token, boolean finished,
            boolean userLeaving, int configChanges, boolean dontReport, int seq) {
     ActivityClientRecord r = mActivities.get(token);
     if (DEBUG_ORDER) Slog.d(TAG, "handlePauseActivity " + r + ", seq: " + seq);
     if (!checkAndUpdateLifecycleSeq(seq, r, "pauseActivity")) {
         return;
     }
     if (r != null) {
         //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
         if (userLeaving) {
             performUserLeavingActivity(r);
         }

         r.activity.mConfigChangeFlags |= configChanges;
         performPauseActivity(token, finished, r.isPreHoneycomb(), "handlePauseActivity");

         // Make sure any pending writes are now committed.
         if (r.isPreHoneycomb()) {
             QueuedWork.waitToFinish();
         }

         // Tell the activity manager we have paused.
         if (!dontReport) {
             try {
                 ActivityManager.getService().activityPaused(token);
             } catch (RemoteException ex) {
                 throw ex.rethrowFromSystemServer();
             }
         }
        mSomeActivitiesChanged = true;
    }
}

调用performPauseActivity方法来调用Activity.onPause方法。
调用ActivityManagerNative.getDefault()对象的activityPaused方法来通知ActivityManagerService处理剩下的事情。

xref:/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

@Override
public final void activityPaused(IBinder token) {
    final long origId = Binder.clearCallingIdentity();
    synchronized(this) {
        ActivityStack stack = ActivityRecord.getStackLocked(token);
        if (stack != null) {
            stack.activityPausedLocked(token, false);
        }
    }
   Binder.restoreCallingIdentity(origId);
}

xref:/frameworks/base/services/core/java/com/android/server/am/ActivityStack.java

final void activityPausedLocked(IBinder token, boolean timeout) {
     final ActivityRecord r = isInStackLocked(token);
     if (r != null) {
         mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
         if (mPausingActivity == r) {
             mService.mWindowManager.deferSurfaceLayout();
             try {
                 completePauseLocked(true /* resumeNext */, null /* resumingActivity */);
             } finally {
                mService.mWindowManager.continueSurfaceLayout();
            }
            return;
        } else {
            if (r.state == ActivityState.PAUSING) {
                r.state = ActivityState.PAUSED;
                if (r.finishing) {
                        finishCurrentActivityLocked(r, FINISH_AFTER_VISIBLE, false);
                    }
               }
            }
       }
        mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
}

resumeNext参数传入的值为true;首先会清空一些状态,将mPausingActivity指向的Activity状态设置为PAUSED,随后并置为null。接着调用ActivityStackSupervisor.resumeFocusedStackTopActivityLocked()函数去启动当前任务栈顶端的Activity,即目标Activity:

private void completePauseLocked(boolean resumeNext, ActivityRecord resuming) {
    ActivityRecord prev = mPausingActivity;
    if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Complete pause: " + prev);
    if (prev != null) {
        final boolean wasStopping = prev.state == STOPPING;
        prev.state = ActivityState.PAUSED;
        ...
        mPausingActivity = null;
    }
     if (resumeNext) {
   final ActivityStack topStack = mStackSupervisor.getFocusedStack();
   if (!mService.isSleepingOrShuttingDownLocked()) {
          mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null);
   } else {
          mStackSupervisor.checkReadyForSleepLocked();
          ActivityRecord top = topStack.topRunningActivityLocked();
          if (top == null || (prev != null && top != prev)) {
               mStackSupervisor.resumeFocusedStackTopActivityLocked();
          }
   }
}
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;
       result = resumeTopActivityInnerLocked(prev, options);
   } finally {
       mStackSupervisor.inResumeTopActivity = false;
   }
   mStackSupervisor.checkReadyForSleepLocked();
   return result;
}
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
      ...
           mStackSupervisor.startSpecificActivityLocked(next, true, true);
       }
        if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
       return true;
}

此时,如果应用进程已经启动,则会去直接启动Activity;否则,先为它启动一个进程
mResumedActivity/mPausingActivity都以置为null;因为,我们需要启动的Activity它的应用进程并未创建过,所以这里需要为它创建一个应用进程:

xref:/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

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

这里的mService代表的是ActivityManagerService, 首先获取即将要启动的activity的所在应用程序的进程, 如果进程已经存在就调用realStartActivityLocked方法
如果应用进程已经启动了,则调用该函数继续处理;其会触发类的onCreate()方法,否则先启动一个进程

xref:/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

private final void startProcessLocked(ProcessRecord app, String hostingType,
3768            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3769        long startTime = SystemClock.elapsedRealtime();
3770        if (app.pid > 0 && app.pid != MY_PID) {
    
    
     startResult = Process.start(entryPoint,
3926                        app.processName, uid, uid, gids, debugFlags, mountExternal,
3927                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3928                        app.info.dataDir, invokeWith, entryPointArgs);
    }

AMS为应用创建进程是借助fork机制实现的,并指定了应用进程的入口函数是ActivityThread::main()
Zygote进程孵化出新的应用进程后,会执行ActivityThread类的main方法。在该方法里会先准备好Looper和消息队列,然后调用attach方法将应用进程绑定到ActivityManagerService,然后进入loop循环,不断地读取消息队列里的消息,并分发消息。

xref:/frameworks/base/core/java/android/app/ActivityThread.java

public static void main(String[] args) {
    ...
    CloseGuard.setEnabled(false);
    Environment.initForCurrentUser();
    EventLogger.setReporter(new EventLoggingReporter());
    final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
    TrustedCertificateStore.setDefaultUserDirectory(configDir);
    Process.setArgV0("<pre-initialized>");
    Looper.prepareMainLooper();
   ActivityThread thread = new ActivityThread();
   thread.attach(false);
   if (sMainThreadHandler == null) {
       sMainThreadHandler = thread.getHandler();
   }
   ...
   Looper.loop();
}

xref:/frameworks/base/core/java/android/app/ActivityThread.java

private void attach(boolean system) {
    sCurrentActivityThread = this;
    mSystemThread = system;
    if (!system) {
        ViewRootImpl.addFirstDrawHandler(new Runnable() {
            @Override
            public void run() {
                ensureJitEnabled();
            }
       });
   
       android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",UserHandle.myUserId());
       RuntimeInit.setApplicationObject(mAppThread.asBinder());
       final IActivityManager mgr = ActivityManager.getService();
       try {
           mgr.attachApplication(mAppThread);
       } catch (RemoteException ex) {
           throw ex.rethrowFromSystemServer();  
       }

       // Watch for getting close to heap limit.
       BinderInternal.addGcWatcher(new Runnable() {
           @Override public void run() {
               if (!mSomeActivitiesChanged) {
                   return;
               }
               Runtime runtime = Runtime.getRuntime();
               long dalvikMax = runtime.maxMemory();
               long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
               if (dalvikUsed > ((3*dalvikMax)/4)) {
               if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024)
                        + " total=" + (runtime.totalMemory()/1024)
                        + " used=" + (dalvikUsed/1024));
                   mSomeActivitiesChanged = false;
                   try {
                       mgr.releaseSomeActivities(mAppThread);
                   } catch (RemoteException e) {
                       throw e.rethrowFromSystemServer();
                   }
               }
          }
     });
   } else {
       // Don't set application object here -- if the system crashes,
       // we can't display an alert, we just want to die die die.
       android.ddm.DdmHandleAppName.setAppName("system_process", UserHandle.myUserId());
       try {
           mInstrumentation = new Instrumentation();
           ContextImpl context = ContextImpl.createAppContext(this, getSystemContext().mPackageInfo);
           mInitialApplication = context.mPackageInfo.makeApplication(true, null);
           mInitialApplication.onCreate();
       } catch (Exception e) {
           throw new RuntimeException("Unable to instantiate Application():" + e.toString(), e);
       }
   }

   // add dropbox logging to libcore
   DropBox.setReporter(new DropBoxReporter());

   ViewRootImpl.ConfigChangedCallback configChangedCallback= (Configuration globalConfig) -> {
       synchronized (mResourcesManager) {
           // We need to apply this change to the resources immediately, because upon returning
           // the view hierarchy will be informed about it.
           if (mResourcesManager.applyConfigurationToResourcesLocked(globalConfig,null /* compat */)) {
               updateLocaleListFromAppContext(mInitialApplication.getApplicationContext(),
                   mResourcesManager.getConfiguration().getLocales());

               // This actually changed the resources! Tell everyone about it.
               if (mPendingConfiguration == null || mPendingConfiguration.isOtherSeqNewer(globalConfig)) {
                   mPendingConfiguration = globalConfig;
                   sendMessage(H.CONFIGURATION_CHANGED, globalConfig);
               }
           }
       }
   };
   ViewRootImpl.addConfigCallback(configChangedCallback);
 }

xref:/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

 @Override
public final void attachApplication(IApplicationThread thread) {
    synchronized (this) {
        int callingPid = Binder.getCallingPid();
        final long origId = Binder.clearCallingIdentity();
        attachApplicationLocked(thread, callingPid);
        Binder.restoreCallingIdentity(origId);
    }
}

xref/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

private final boolean attachApplicationLocked(IApplicationThread thread, int pid) {
    try {
         ...
         thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
                profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
                app.instrumentationUiAutomationConnection, testMode,
                mBinderTransactionTrackingEnabled, enableTrackAllocation,
                isRestrictedBackupMode || !normalMode, app.persistent,
                new Configuration(mConfiguration), app.compat,
               getCommonServicesLocked(app.isolated),
               mCoreSettingsObserver.getCoreSettingsLocked());//调用bindApplication()方法
        updateLruProcessLocked(app, false, null);
        app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
   } catch (Exception e) {
           ...
   }
        
   if (normalMode) {
   try {
       if (mStackSupervisor.attachApplicationLocked(app)) {
             didSomething = true;
       }
   } catch (Exception e) {
 }
}

thread对象其实是ActivityThread里ApplicationThread对象在ActivityManagerService的代理对象,故此执行thread.bindApplication,最终会调用ApplicationThread的bindApplication方法

public final void bindApplication(String processName, ApplicationInfo appInfo,
             List<ProviderInfo> providers, ComponentName instrumentationName,
             ProfilerInfo profilerInfo, Bundle instrumentationArgs,
             IInstrumentationWatcher instrumentationWatcher,
             IUiAutomationConnection instrumentationUiConnection, int debugMode,
             boolean enableBinderTracking, boolean trackAllocation,
             boolean isRestrictedBackupMode, boolean persistent, Configuration config,
             CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
             String buildSerial) {
    
    if (services != null) {
        // Setup the service cache in the ServiceManager
        ServiceManager.initServiceCache(services);
    }

    setCoreSettings(coreSettings);

    AppBindData data = new AppBindData();
    data.processName = processName;
    data.appInfo = appInfo;
    data.providers = providers;
    data.instrumentationName = instrumentationName;
    data.instrumentationArgs = instrumentationArgs;
    data.instrumentationWatcher = instrumentationWatcher;
    data.instrumentationUiAutomationConnection = instrumentationUiConnection;
    data.debugMode = debugMode;
    data.enableBinderTracking = enableBinderTracking;
    data.trackAllocation = trackAllocation;
    data.restrictedBackupMode = isRestrictedBackupMode;
    data.persistent = persistent;
    data.config = config;
    data.compatInfo = compatInfo;
    data.initProfilerInfo = profilerInfo;
    data.buildSerial = buildSerial;
    sendMessage(H.BIND_APPLICATION, data);
  }
private void handleBindApplication(AppBindData data) {
     VMRuntime.registerSensitiveThread();
     if (data.trackAllocation) {
         DdmVmInternal.enableRecentAllocations(true);
     }

     // Note when this process has started.
     Process.setStartTimes(SystemClock.elapsedRealtime(), SystemClock.uptimeMillis());

    // send up app name; do this *before* waiting for debugger
    Process.setArgV0(data.processName);
    android.ddm.DdmHandleAppName.setAppName(data.processName, UserHandle.myUserId());

    data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
 
    final InstrumentationInfo ii;
    if (data.instrumentationName != null) {
        try {
            ii = new ApplicationPackageManager(null, getPackageManager())
                     .getInstrumentationInfo(data.instrumentationName, 0);
        } catch (PackageManager.NameNotFoundException e) {
            throw new RuntimeException(
                    "Unable to find instrumentation info for: " + data.instrumentationName);
        }

        mInstrumentationPackageName = ii.packageName;
        mInstrumentationAppDir = ii.sourceDir;
        mInstrumentationSplitAppDirs = ii.splitSourceDirs;
        mInstrumentationLibDir = getInstrumentationLibrary(data.appInfo, ii);
        mInstrumentedAppDir = data.info.getAppDir();
        mInstrumentedSplitAppDirs = data.info.getSplitAppDirs();
        mInstrumentedLibDir = data.info.getLibDir();
    } else {
        ii = null;
    }

    final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
    updateLocaleListFromAppContext(appContext, mResourcesManager.getConfiguration().getLocales());

    if (!Process.isIsolated() && !"android".equals(appContext.getPackageName())) {
        // This cache location probably points at credential-encrypted
        // storage which may not be accessible yet; assign it anyway instead
        // of pointing at device-encrypted storage.
        final File cacheDir = appContext.getCacheDir();
        if (cacheDir != null) {
            // Provide a usable directory for temporary files
            System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());
        } else {
            Log.v(TAG, "Unable to initialize \"java.io.tmpdir\" property "+ "due to missing cache directory");
    }

    // Setup a location to store generated/compiled graphics code.
    final Context deviceContext = appContext.createDeviceProtectedStorageContext();
    final File codeCacheDir = deviceContext.getCodeCacheDir();
    if (codeCacheDir != null) {
        setupGraphicsSupport(appContext, codeCacheDir);
    } else {
        Log.e(TAG, "Unable to setupGraphicsSupport due to missing code-cache directory");
    }
   
    // Continue loading instrumentation.
    if (ii != null) {
        final ApplicationInfo instrApp = new ApplicationInfo();
        ii.copyTo(instrApp);
        instrApp.initForUser(UserHandle.myUserId());
        final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
                  appContext.getClassLoader(), false, true, false);
        final ContextImpl instrContext = ContextImpl.createAppContext(this, pi);

        try {
            final ClassLoader cl = instrContext.getClassLoader();
            mInstrumentation = (Instrumentation) cl.loadClass(data.instrumentationName.getClassName()).newInstance();
        } catch (Exception e) {
            throw new RuntimeException("Unable to instantiate instrumentation "
                  + data.instrumentationName + ": " + e.toString(), e);
        }
        final ComponentName component = new ComponentName(ii.packageName, ii.name);
        mInstrumentation.init(this, instrContext, appContext, component,
                  data.instrumentationWatcher, data.instrumentationUiAutomationConnection);
        if (mProfiler.profileFile != null && !ii.handleProfiling && mProfiler.profileFd == null) {
            mProfiler.handlingProfiling = true;
            final File file = new File(mProfiler.profileFile);
            file.getParentFile().mkdirs();
            Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
        }
    } else {
        mInstrumentation = new Instrumentation();
    }

    if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) {
        dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
    } else {
        // Small heap, clamp to the current growth limit and let the heap release
        // pages after the growth limit to the non growth limit capacity. b/18387825
        dalvik.system.VMRuntime.getRuntime().clampGrowthLimit();
    }

    // Allow disk access during application and provider setup. This could
    // block processing ordered broadcasts, but later processing would
   // probably end up doing the same disk access.
   final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
   try {
       // If the app is being launched for full backup or restore, bring it up in
       // a restricted environment with the base application class.
       Application app = data.info.makeApplication(data.restrictedBackupMode, null);
       mInitialApplication = app;

       // Do this after providers, since instrumentation tests generally start their
       // test thread at this point, and we don't want that racing.
       try {
           mInstrumentation.onCreate(data.instrumentationArgs);
       } catch (Exception e) {
       }

       try {
           mInstrumentation.callApplicationOnCreate(app);
       } catch (Exception e) {
       }
     }

     // Preload fonts resources
     FontsContract.setApplicationContextForResources(appContext);
     try {
         final ApplicationInfo info = getPackageManager().getApplicationInfo(
                            data.appInfo.packageName,
                            PackageManager.GET_META_DATA /*flags*/,
                            UserHandle.myUserId());
         if (info.metaData != null) {
             final int preloadedFontsResource = info.metaData.getInt(
                     ApplicationInfo.METADATA_PRELOADED_FONTS, 0);
             if (preloadedFontsResource != 0) {
                 data.info.mResources.preloadFonts(preloadedFontsResource);
             }
         }
       } catch (RemoteException e) {
    }
}

从代码可以得知,一个ActivityThread对象,即一个应用的主线程中只会存在一个LoadedApk、Instrumentation、Application等实例,它们在一个应用进程中被所有Activity共用。

接着调用ActivityStackSupervisor.attachApplicationLocked()在该进程启动当前的目标Activity:

boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
    final String processName = app.processName;
    boolean didSomething = false;
    for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
        ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
        for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
            final ActivityStack stack = stacks.get(stackNdx);
            if (!isFocusedStack(stack)) {
                 continue;
           }
           ActivityRecord hr = stack.topRunningActivityLocked();
           if (hr != null) {
               if (hr.app == null && app.uid == hr.info.applicationInfo.uid
                         && processName.equals(hr.processName)) {
                   try {
                       if (realStartActivityLocked(hr, app, true, true)) {
                           didSomething = true;
                       }
                   } catch (RemoteException e) {
                   }
               }
           }
       }
   }
   if (!didSomething) {
      ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
   }
   return didSomething;
  }

首先得到当前任务栈顶端的Activity,它既是我们当前需要启动的目标。因为该Activity尚未启动,所以会去调用realStartActivityLocked()去启动:

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
          boolean andResume, boolean checkConfig) throws RemoteException {
   ...
   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);
   ...      
  return true;
}

app是一个ProcessRecord对象, app.thread 类型是 IApplicationThread,因此app.thread是一个IApplicationThread的代理对象;它的实现是 ActivityThread 的内部类 ApplicationThread,ApplicationThread继承了 IApplicationThread.Stub。
app指的是传入的要启动的Activity的所在的应用程序进程,当前代码逻辑运行在AMS所在的进程(SyetemServer进程),
通过ApplicationThread来与应用程序进程进行Binder通信,换句话说,ApplicationThread是AMS所在进程(SyetemServer进程)和应用程序进程的通信桥梁

app.thread调用scheduleLaunchActivity方法,通过Binder机制,会使ApplicationThread$scheduleLaunchActivity方法被调用。
于是,基于Binder机制,实现了一次进程间的通信,将启动Activity的操作交给了ApplicationThread类。

这样调用queueOrSendMessage会往ActivityThread的消息队列发送消息,消息的用途是BIND_APPLICATION。

3. ActivityThread 启动 Activity;

xref:/frameworks/base/core/java/android/app/ActivityThread.java

private class ApplicationThread extends IApplicationThread.Stub {
    ... 
    @Override
    public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
            ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
            CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
            int procState, Bundle state, PersistableBundle persistentState,
            List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
            boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {

       updateProcessState(procState, false);

       ActivityClientRecord r = new ActivityClientRecord();
       r.token = token;
       r.ident = ident;
       r.intent = intent;
       r.referrer = referrer;
       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;

       r.overrideConfig = overrideConfig;
       updatePendingConfiguration(curConfig);

       sendMessage(H.LAUNCH_ACTIVITY, r);
   }
}    
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
    if (DEBUG_MESSAGES) Slog.v(
            TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
            + ": " + arg1 + " / " + obj);
    Message msg = Message.obtain();
    msg.what = what;
    msg.obj = obj;
    msg.arg1 = arg1;
    msg.arg2 = arg2;
   if (async) {
      msg.setAsynchronous(true);
   }
   mH.sendMessage(msg);
}

首先将所有参数组装成一个ActivityClientRecord, 然后通过mH成员变量发送msg出去,mH的类型是H,其实就是继承于Handler类,是ActivityThread的内部类,所以该消息最后由 H.handleMessage 来处理。

private class H extends Handler {
    public static final int LAUNCH_ACTIVITY         = 100;
    public static final int PAUSE_ACTIVITY          = 101;
    
    ...
    
    public void handleMessage(Message msg) {
        if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) {
               case LAUNCH_ACTIVITY: {
                   Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
                   final ActivityClientRecord r = (ActivityClientRecord) msg.obj;

                   r.packageInfo = getPackageInfoNoCheck(r.activityInfo.applicationInfo, r.compatInfo);
                   handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
                   Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
               } 
               break;
               case RELAUNCH_ACTIVITY: {
                   Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");
                   ActivityClientRecord r = (ActivityClientRecord)msg.obj;
                   handleRelaunchActivity(r);
                   Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
               } break;
               case PAUSE_ACTIVITY: {
                   Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
                   SomeArgs args = (SomeArgs) msg.obj;
                   handlePauseActivity((IBinder) args.arg1, false,
                           (args.argi1 & USER_LEAVING) != 0, args.argi2,
                           (args.argi1 & DONT_REPORT) != 0, args.argi3);
                   maybeSnapshot();
                   Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
              } break;
              
              ...

通过getPackageInfoNoCheck方法获得LoadedApk类型的对象并赋值给ActivityClientRecord 的成员变量packageInfo,
应用程序进程要启动Activity时需要将该Activity所属的APK加载进来,而LoadedApk就是用来描述已加载的APK文件

首先会将AMS传入的参数封装成ActivityClientRecord对象,然后调用ActivityThread::handleLaunchActivity():

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
    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);

      // Initialize before creating the activity
      WindowManagerGlobal.initialize();

      Activity a = performLaunchActivity(r, customIntent);

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

          if (!r.activity.mFinished && r.startsNotResumed) {
              performPauseActivityIfNeeded(r, reason);
              if (r.isPreHoneycomb()) {
                  r.state = oldState;
              }
          }
      } else {
           // If there was an error, for any reason, tell the activity manager to stop us.
            try {
                ActivityManager.getService()
                    .finishActivity(r.token, Activity.RESULT_CANCELED, null,
                            Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
      }
}
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    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);
   }

   ContextImpl appContext = createBaseContextForActivity(r);
   Activity activity = null;
   try {
       java.lang.ClassLoader cl = appContext.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 (activity != null) {
           CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
           Configuration config = new Configuration(mCompatConfiguration);
           if (r.overrideConfig != null) {
               config.updateFrom(r.overrideConfig);
           }
           
           Window window = null;
           if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
               window = r.mPendingRemoveWindow;
               r.mPendingRemoveWindow = null;
               r.mPendingRemoveWindowManager = null;
           }
           appContext.setOuterContext(activity);
           activity.attach(appContext, this, getInstrumentation(), r.token,
                    r.ident, app, r.intent, r.activityInfo, title, r.parent,
                    r.embeddedID, r.lastNonConfigurationInstances, config,
                    r.referrer, r.voiceInteractor, window, r.configCallback);

           if (customIntent != null) {
                activity.mIntent = customIntent;
           }
           r.lastNonConfigurationInstances = null;
           checkAndBlockForNetworkAccess();
           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;
}

首先获取ActivityInfo, 然后通过activityinfo的信息去获取LoadedApk, LoadedApk是描述一个APK文件信息的类;
然后创建启动该 activity 的上下文 appContext, 后面会用这个context去获取classloader,为后面创建activity实例做准备;

Application app = r.packageInfo.makeApplication(false, mInstrumentation); 创建Application,
attach初始化activity,创建window对象,phoneWindow; 接下来调用 mInstrumentation 的callActivityOnCreate启动activity

首先获取当前Activity的全限定名,并通过ClassLoader来加载当前的Activity类,并创建该Activity的一个实例;随后会为当前应用创建上下文对象及其他信息,并与该Activity关联起来;这部分内容,后续再分析,此处我们只关注Activity生命周期相关的内容。接着:

Instrumentation.callActivityOnCreate()函数会根据当前Activity的实例去调用它的onCreate()函数
Activity.performStart()函数会去调用当前Activity的onStart()函数
会将当前当前启动的Activity信息保存到ActivityThread::mActivities集合中

xref:/frameworks/base/core/java/android/app/Instrumentation.java

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

推荐阅读更多精彩内容