Activity的啟動(dòng)流程

一西雀、用戶啟動(dòng)Activity甥捺,發(fā)送消息給ATMS的過程(Launcher > ATMS階段)

開發(fā)中我們會(huì)調(diào)用startActivity來啟動(dòng)一個(gè)Activity微姊,最終會(huì)調(diào)到startActivityForResult

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
       @Nullable Bundle options) {
  //通過Instrumentation啟動(dòng)Activity
  Instrumentation.ActivityResult ar =
    mInstrumentation.execStartActivity(
        this, mMainThread.getApplicationThread(), mToken, this,
        intent, requestCode, options);
}

Instrumentation是Android系統(tǒng)里面的一套控制方法或者“鉤子”。這些鉤子可以在正常的生命周期(正常是由操作系統(tǒng)控制的)之外控制Android控件的運(yùn)行慈缔。

Application和Activity的所有生命周期中袱衷,都會(huì)先調(diào)用Instrumentation提供的相應(yīng)方法(如callActivityOnCreate捎废,callApplicationOnCreate,newActivity致燥,callActivityOnNewIntent)

Instrumentation.execStartActivity

public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, String target,
        Intent intent, int requestCode, Bundle options) {
  //通過ATMS啟動(dòng)Activity(API 29是ATMS)
  int result = ActivityTaskManager.getService()
    .startActivity(whoThread, who.getBasePackageName(), intent,
                   intent.resolveTypeIfNeeded(who.getContentResolver()),
                   token, target, requestCode, 0, null, options);
  
}
public static IActivityTaskManager getService() {
    return IActivityTaskManagerSingleton.get();
}

@UnsupportedAppUsage(trackingBug = 129726065)
private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
        new Singleton<IActivityTaskManager>() {
            @Override
            protected IActivityTaskManager create() {
                //找到Binder服務(wù)
                final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
                return IActivityTaskManager.Stub.asInterface(b);
            }
        };

ActivityTaskManager.getService()返回了一個(gè)IActivityTaskManager登疗,拿到的是ATMS的代理對象,跨進(jìn)程調(diào)用了ATMS的startActivity方法嫌蚤。

二辐益、ATMS接收到啟動(dòng)請求并處理的過程(ATMS > ApplicationThread階段)
//ActivityTaskManagerService.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());
}

int startActivityAsUser(IApplicationThread caller, String callingPackage,
   Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
   int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
   boolean validateIncomingUser) {
        enforceNotIsolatedCaller("startActivityAsUser");
        userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
                Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");

        // TODO: Switch to user app stacks here.
        return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
                .setCaller(caller)
                .setCallingPackage(callingPackage)
                .setResolvedType(resolvedType)
                .setResultTo(resultTo)
                .setResultWho(resultWho)
                .setRequestCode(requestCode)
                .setStartFlags(startFlags)
                .setProfilerInfo(profilerInfo)
                .setActivityOptions(bOptions)
                .setMayWait(userId)
                    //調(diào)用了ActivityStarter的execute
                .execute();
    }
int execute() {
  return startActivityMayWait(/**省略參數(shù)**/);
}

ActivityStarter.startActivityMayWait

//ActivityStarter.java
private int startActivityMayWait(/**省略參數(shù)**/){
  //收集目標(biāo)Intent信息(更加Intent的action,可用于雙開脱吱,選擇打開)
  ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
  
  int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
          voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
          callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
          ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
          allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent,
          allowBackgroundActivityStart);
}

private int startActivity(/**省略參數(shù)**/){
  mLastStartActivityResult = startActivity(/**省略參數(shù)**/)
}

private int startActivity(/**省略參數(shù)**/){
  //處理startActivityForResult智政,對result進(jìn)行轉(zhuǎn)發(fā)
  final int launchFlags = intent.getFlags();
  if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
    // Transfer the result target from the source activity to the new
    // one being started, including any failures.
    if (requestCode >= 0) {
      SafeActivityOptions.abort(options);
      return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
    }
    resultRecord = sourceRecord.resultTo;
    if (resultRecord != null && !resultRecord.isInStackLocked()) {
      resultRecord = null;
    }
    resultWho = sourceRecord.resultWho;
    requestCode = sourceRecord.requestCode;
    sourceRecord.resultTo = null;
    if (resultRecord != null) {
      resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode);
    }
    if (sourceRecord.launchedFromUid == callingUid) {
      // The new activity is being launched from the same uid as the previous
      // activity in the flow, and asking to forward its result back to the
      // previous.  In this case the activity is serving as a trampoline between
      // the two, so we also want to update its launchedFromPackage to be the
      // same as the previous activity.  Note that this is safe, since we know
      // these two packages come from the same uid; the caller could just as
      // well have supplied that same package name itself.  This specifially
      // deals with the case of an intent picker/chooser being launched in the app
      // flow to redirect to an activity picked by the user, where we want the final
      // activity to consider it to have been launched by the previous app activity.
      callingPackage = sourceRecord.launchedFromPackage;
    }
  }
  
  //接下來做一些校驗(yàn)判斷
  
  //從Intent中找不到相應(yīng)Component
  if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
    // We couldn't find a class that can handle the given Intent.
    // That's the end of that!
    err = ActivityManager.START_INTENT_NOT_RESOLVED;
  }
  //從Intent中找不到相應(yīng)AppInfo
  if (err == ActivityManager.START_SUCCESS && aInfo == null) {
    // We couldn't find the specific class specified in the Intent.
    // Also the end of the line.
    err = ActivityManager.START_CLASS_NOT_FOUND;
  }
  //...
  //校驗(yàn)當(dāng)前應(yīng)用是否開啟權(quán)限
  boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,
                requestCode, callingPid, callingUid, callingPackage, ignoreTargetSecurity,
                inTask != null, callerApp, resultRecord, resultStack);
  
  //創(chuàng)建目標(biāo)ActivityRecord對象,存數(shù)組索引為0的位置
  ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
           callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
           resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
           mSupervisor, checkedOptions, sourceRecord);
  if (outActivity != null) {
    outActivity[0] = r;
  }
  //繼續(xù)調(diào)用startActivity
  final int res = startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
        true /* doResume */, checkedOptions, inTask, outActivity, restrictedBgActivity);
  return res;
}

private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity, boolean restrictedBgActivity) {
  //startActivityUnchecked
  result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
          startFlags, doResume, options, inTask, outActivity, restrictedBgActivity);
}

ActivityStarter中做了一系列的調(diào)用(收集Intent信息急凰,處理startActivityForResult女仰,做一些校驗(yàn)判斷等)猜年,最終進(jìn)入startActivityUnchecked抡锈。

startActivityUnchecked

// Note: This method should only be called from {@link startActivity}.
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
        ActivityRecord[] outActivity, boolean restrictedBgActivity) {
  //根據(jù)Intent識(shí)別啟動(dòng)模式
  setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
            voiceInteractor, restrictedBgActivity);
    //判斷啟動(dòng)模式,并在mLaunchFlags追加對應(yīng)的標(biāo)記
  computeLaunchingTaskFlags();
  //獲取Activity的啟動(dòng)棧
  computeSourceStack();
  //根據(jù)上面的計(jì)算乔外,設(shè)置Intent的flags
  mIntent.setFlags(mLaunchFlags);
  
  //處理完啟動(dòng)棧后床三,準(zhǔn)備執(zhí)行發(fā)起者的Resume狀態(tài)了
  if (mDoResume) {
    //resume我們的Activity
     mRootActivityContainer.resumeFocusedStacksTopActivities(
            mTargetStack, mStartActivity, mOptions);
  }
}

startActivityUnchecked中處理了關(guān)于Activity啟動(dòng)模式的處理,接著真正的resume我們的Activity

//RootActivityContainer.java
boolean resumeFocusedStacksTopActivities(
        ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
  //調(diào)用ActivityStack(Activity棧)的resumeTopActivityUncheckedLocked方法
  result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
//ActivityStack.java
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
  result = resumeTopActivityInnerLocked(prev, options);
}

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
  //將發(fā)起者置為onPause狀態(tài)
  boolean pausing = getDisplay().pauseBackStacks(userLeaving, next, false);
  //繼續(xù)當(dāng)前Activity
  mStackSupervisor.startSpecificActivityLocked(next, true, true);
}
//ActivityStackSupervisor.java
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
  // Is this activity's application already running?
  final WindowProcessController wpc =
           mService.getProcessController(r.processName, r.info.applicationInfo.uid);
  
  boolean knownToBeDead = false;
  if (wpc != null && wpc.hasThread()) {
    try {
      //如果這個(gè)app已經(jīng)啟動(dòng)杨幼,執(zhí)行realStartActivityLocked并return(熱啟動(dòng))
      realStartActivityLocked(r, wpc, 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.
    knownToBeDead = true;
  }
  
  // Post message to start process to avoid possible deadlock of calling into AMS with the
  // ATMS lock held.
  //創(chuàng)建應(yīng)用進(jìn)程
  final Message msg = PooledLambda.obtainMessage(
    ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
    r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
  mService.mH.sendMessage(msg);
}

這里會(huì)先判斷應(yīng)用進(jìn)程是否創(chuàng)建,創(chuàng)建了就進(jìn)入realStartActivityLocked,沒創(chuàng)建就會(huì)調(diào)用ActivityManagerInternal.startProcess

①熱啟動(dòng)realStartActivityLocked

//ActivityStackSupervisor.java
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
        boolean andResume, boolean checkConfig) throws RemoteException {
  // Create activity launch transaction.
  final ClientTransaction clientTransaction = ClientTransaction.obtain(
                    proc.getThread(), r.appToken);
  
  //addCallback捣卤,傳入?yún)?shù)LaunchActivityItem
  clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
           System.identityHashCode(r), r.info,
           // TODO: Have this take the merged configuration instead of separate global
           // and override configs.
           mergedConfiguration.getGlobalConfiguration(),
           mergedConfiguration.getOverrideConfiguration(), r.compat,
           r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
           r.icicle, r.persistentState, results, newIntents,
           dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
           r.assistToken));
  // Schedule transaction.
  //獲取ClientLifecycleManager對象進(jìn)行調(diào)度
  mService.getLifecycleManager().scheduleTransaction(clientTransaction);
}
//ClientLifecycleManager.java
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
  final IApplicationThread client = transaction.getClient();
  //調(diào)用ClientTransaction的schedule
  transaction.schedule();
  if (!(client instanceof Binder)) {
    // If client is not an instance of Binder - it's a remote call and at this point it is
    // safe to recycle the object. All objects used for local calls will be recycled after
    // the transaction is executed on client in ActivityThread.
    transaction.recycle();
  }
}
//ClientTransaction.java

/** Target client. */
private IApplicationThread mClient;

public void schedule() throws RemoteException {
  //mClient為IApplicationThread耕肩,調(diào)度到主進(jìn)程處理
  mClient.scheduleTransaction(this);
}
三、ApplicationThread接收到調(diào)度請求并處理的過程(Application > Activity階段)
private class ApplicationThread extends IApplicationThread.Stub {
  
  @Override
  public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
    ActivityThread.this.scheduleTransaction(transaction);
  }
}
public abstract class ClientTransactionHandler {

    // Schedule phase related logic and handlers.

    /** Prepare and schedule transaction for execution. */
    void scheduleTransaction(ClientTransaction transaction) {
        transaction.preExecute(this);
        //發(fā)送消息給H(H是ActivityThread的一個(gè)內(nèi)部類)
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }
}

接著看ActivityThread中接收并處理消息的handleMessage

public void handleMessage(Message msg) {
  switch (msg.what) {
    case EXECUTE_TRANSACTION:
      final ClientTransaction transaction = (ClientTransaction) msg.obj;
      //取出消息欲逃,執(zhí)行execute方法
      mTransactionExecutor.execute(transaction);
      if (isSystem()) {
        // Client transactions inside system process are recycled on the client side
        // instead of ClientLifecycleManager to avoid being cleared before this
        // message is handled.
        transaction.recycle();
      }
      // TODO(lifecycler): Recycle locally scheduled transactions.
      break;
  }
}
//TransactionExecutor.java
public void execute(ClientTransaction transaction) {
  executeCallbacks(transaction);
    executeLifecycleState(transaction);
}

public void executeCallbacks(ClientTransaction transaction) {
  final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
  
  final int size = callbacks.size();
  for (int i = 0; i < size; ++i) {
    //取出上面realStartActivityLocked中設(shè)置的LaunchActivityItem類型的CallBack
    final ClientTransactionItem item = callbacks.get(i);
    //調(diào)用LaunchActivityItem的execute
    item.execute(mTransactionHandler, token, mPendingActions);
    item.postExecute(mTransactionHandler, token, mPendingActions);
  }
}

前面realStartActivityLocked方法中通過addCallback找蜜,傳入?yún)?shù)LaunchActivityItem。executeCallbacks方法中取出callbacks集合中的LaunchActivityItem稳析,并調(diào)用其execute方法

//LaunchActivityItem.java
@Override
public void execute(ClientTransactionHandler client, IBinder token,
        PendingTransactionActions pendingActions) {
  Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
  ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
        mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
      mPendingResults, mPendingNewIntents, mIsForward,
      mProfilerInfo, client, mAssistToken);
  //ClientTransactionHandler的子類ActivityThread執(zhí)行handleLaunchActivity方法
  client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
  Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}

handleLaunchActivity

//ActivityThread.java
@Override
public Activity handleLaunchActivity(ActivityClientRecord r,
        PendingTransactionActions pendingActions, Intent customIntent) {
  
    final Activity a = performLaunchActivity(r, customIntent);
}

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
  //通過Instrumentation創(chuàng)建Activity
  activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
  //拿到Application
  Application app = r.packageInfo.makeApplication(false, mInstrumentation);
  //調(diào)用Activity的attach
  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,
                        r.assistToken);
  //通過Instrumentation調(diào)用Activity的onCreate方法
  mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
    //設(shè)置狀態(tài)
  r.setState(ON_CREATE);
}

②冷啟動(dòng)創(chuàng)建應(yīng)用進(jìn)程ActivityManagerInternal.startProcess

ActivityManagerInternal的實(shí)現(xiàn)類是AMS中的LocalService洗做,AMS通過Socket與Zygote通信弓叛,fork出App進(jìn)程,app進(jìn)程創(chuàng)建后诚纸,會(huì)執(zhí)行ActivityThread的main方法(Android進(jìn)程入口方法)

//ActivityThread.java
public static void main(String[] args) {
  //創(chuàng)建Looper
  Looper.prepareMainLooper();
  //創(chuàng)建ActivityThread
  ActivityThread thread = new ActivityThread();
  //[1]attach
  thread.attach(false, startSeq);
  //loop循環(huán)
  Looper.loop();
}

調(diào)用ActivityThread的attach

private void attach(boolean system, long startSeq) {
  //system傳的false
  
  final IActivityManager mgr = ActivityManager.getService();
  //[2]調(diào)用AMS的attachApplication
  mgr.attachApplication(mAppThread, startSeq);
}
//ActivityManagerService.java
@Override
public final void attachApplication(IApplicationThread thread, long startSeq) {
    synchronized (this) {
        int callingPid = Binder.getCallingPid();
        final int callingUid = Binder.getCallingUid();
        final long origId = Binder.clearCallingIdentity();
        //[3]attachApplicationLocked
        attachApplicationLocked(thread, callingPid, callingUid, startSeq);
        Binder.restoreCallingIdentity(origId);
    }
}

private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid, int callingUid, long startSeq) {
  
  //[4]bindApplication
  thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
         null, null, null, testMode,
         mBinderTransactionTrackingEnabled, enableTrackAllocation,
         isRestrictedBackupMode || !normalMode, app.isPersistent(),
         new Configuration(app.getWindowProcessController().getConfiguration()),
         app.compat, getCommonServicesLocked(app.isolated),
         mCoreSettingsObserver.getCoreSettingsLocked(),
         buildSerial, autofillOptions, contentCaptureOptions);
  
  app.makeActive(thread, mProcessStats);
  //[5]調(diào)用ATMS的attachApplication
  didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
}

[4]thread.bindApplication 這是一個(gè)binder通信的過程

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, boolean autofillCompatibilityEnabled) {
  
  //創(chuàng)建一個(gè)AppBindData
  AppBindData data = new AppBindData();
  data.processName = processName;
  data.appInfo = appInfo;
  data.providers = providers;
  //...data賦值操作...
  //最后發(fā)送Handler消息
  sendMessage(H.BIND_APPLICATION, data);
}

ActivityThread內(nèi)部的Handler接收到BIND_APPLICATION消息

case BIND_APPLICATION:
    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
    AppBindData data = (AppBindData)msg.obj;
    handleBindApplication(data);
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    break;
private void handleBindApplication(AppBindData data) {
  //獲取LoadedApk對象
  data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
  //創(chuàng)建ContextImpl上下文
  final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
  //創(chuàng)建Instrumentation
  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);
  }
  //通過反射創(chuàng)建目標(biāo)Application對象
  app = data.info.makeApplication(data.restrictedBackupMode, null);
  //調(diào)用Application的onCreate方法
  mInstrumentation.callApplicationOnCreate(app);
}

回到上面attachApplicationLocked的mAtmInternal.attachApplication撰筷,調(diào)用ATMS的attachApplication

//ActivityTaskManagerService.java
public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
  synchronized (mGlobalLockWithoutBoost) {
    return mRootActivityContainer.attachApplication(wpc);
  }
}
//RootActivityContainer.java
boolean attachApplication(WindowProcessController app) throws RemoteException {
  //看到了似曾相識(shí)的realStartActivityLocked。
  mStackSupervisor.realStartActivityLocked(activity, app,
                  top == activity /* andResume */, true /* checkConfig */)
}

看到了似曾相識(shí)的realStartActivityLocked畦徘,后面流程和之前一樣毕籽。Activity啟動(dòng)流程分析完畢。

總結(jié)

1)與Activity管理有關(guān)的類:

ActivityRecord:歷史棧中的一個(gè)條目井辆,代表一個(gè)Activity

TaskRecord:內(nèi)部維護(hù)了一個(gè)ArrayList<ActivityRecord> 影钉,來保存ActivityRecord

ActivityStack:內(nèi)部維護(hù)了一個(gè)ArrayList<TaskRecord>,用來管理TaskRecord

ActivityStackSupervisor:用來管理ActivityStack的

2)Activity啟動(dòng)流程

  1. Launcher > ATMS階段


    Launcher>ATMS階段.png
  2. ATMS > ApplicationThread階段


    ATMS > ApplicationThread階段.png
  3. ApplicationThread > Activity階段


    ApplicationThread > Activity階段.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末掘剪,一起剝皮案震驚了整個(gè)濱河市平委,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌夺谁,老刑警劉巖廉赔,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異匾鸥,居然都是意外死亡蜡塌,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進(jìn)店門勿负,熙熙樓的掌柜王于貴愁眉苦臉地迎上來馏艾,“玉大人,你說我怎么就攤上這事奴愉±拍Γ” “怎么了?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵锭硼,是天一觀的道長房资。 經(jīng)常有香客問我,道長檀头,這世上最難降的妖魔是什么轰异? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮暑始,結(jié)果婚禮上搭独,老公的妹妹穿的比我還像新娘。我一直安慰自己廊镜,他們只是感情好牙肝,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般惊奇。 火紅的嫁衣襯著肌膚如雪互躬。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天颂郎,我揣著相機(jī)與錄音吼渡,去河邊找鬼。 笑死乓序,一個(gè)胖子當(dāng)著我的面吹牛寺酪,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播替劈,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼寄雀,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了陨献?” 一聲冷哼從身側(cè)響起盒犹,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎眨业,沒想到半個(gè)月后急膀,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡龄捡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年卓嫂,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片聘殖。...
    茶點(diǎn)故事閱讀 40,030評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡晨雳,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出奸腺,到底是詐尸還是另有隱情餐禁,我是刑警寧澤,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布洋机,位于F島的核電站坠宴,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏绷旗。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一副砍、第九天 我趴在偏房一處隱蔽的房頂上張望衔肢。 院中可真熱鬧,春花似錦豁翎、人聲如沸角骤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽邦尊。三九已至背桐,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蝉揍,已是汗流浹背链峭。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留又沾,地道東北人弊仪。 一個(gè)月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像杖刷,于是被迫代替她去往敵國和親励饵。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評論 2 355

推薦閱讀更多精彩內(nèi)容