天天看點

Android元件管理架構—視圖容器Activity之啟動流程(Android P)

一 前言

        一般像這種源碼調用流程會比較長和繞,我們在分析的時候要有一定學習目标(比如這個實作的功能,為什麼這樣實作),有目标就不會迷失;先熟悉大緻流程;抓住關鍵地方;某些細節的東西需要的時候再去研究。個人覺得既然研究的對象是源碼,那麼分析的大部分将還是以源碼的形式展示較好。要想在哪方面長進,那麼就在那裡翻滾;要想懂得深淵,那麼請先凝視深淵,這樣深淵才會凝視你。

學習目标

     (1) Launcher元件的認識;

     (2) 點選桌面上的圖示(Launcher.apk的界面),進入另一個App的流程;

     (3) ActivityManagerServices(AMS)、ActivityStack、ActivityThread、Instrumentation等Android framework中重要的基礎類的作用及互相間的關系;

     (4) AMS和ActivityThread在控制Activity生命周期起到的作用和互相之間的關系;

     (5) Activity相關的framework層。

二 圖示調用流程

在這部分可以熟悉大緻流程。

Android元件管理架構—視圖容器Activity之啟動流程(Android P)

三 代碼具體流程

         通過對代碼具體流程的分析可以進一步抓住關鍵地方,并注意某些細節。

         相關源碼位置

frameworks/base/core/java/android/app/
   Activity.java
   Instrumentation.java
   IActivityManager.java
   ActivityManager.java
   IApplicationThread.java
   ActivityThread.java (内含ApplicationThread)
   ClientTransactionHandler.java
 
   util/Singleton.java
   
   servertransaction/ClientTransaction.java
   servertransaction\TransactionExecutor.java
   servertransaction\ClientTransactionItem.java
   servertransaction\LaunchActivityItem.java
  

frameworks/base/services/core/java/com/android/server/am/
   ActivityManagerService.java
   ActivityStartController.java
   ActivityStarter.java
   ActivityStackSupervisor.java
   ActivityStack.java
   ClientLifecycleManager.java
           

        Activity的啟動有兩種情況,一種是點選桌面的應用圖示啟動,另一種是在應用内部啟動。不管是從桌面進入應用主界面,還是在應用裡進入一個新的Activity,最終都會調用Activity$startActivity方法。我們先分析點選桌面圖示啟動的這種情況。

       當我們點選手機桌面上的圖示的時候,App就由Launcher.apk開始啟動了,Launcher.apk本質上也是一個應用程式,運作在自己的程序中,我們看到的桌面就是 Launcher 中的一個 Activity。Launcher實作了點選、長按等回調接口,來接收使用者的輸入。

1 packages/apps/Launcher2/src/com/android/launcher2/Launcher.java

/**
* Default launcher application.
*/
public final class Launcher extends Activity
        implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks,
                   View.OnTouchListener {
           

當監聽到Launcher這個Activity上的圖示被點選會觸發相關函數。

/**
* Launches the intent referred by the clicked shortcut.
*
* @param v The view representing the clicked shortcut.
*/
public void onClick(View v) {
    // Make sure that rogue clicks don't get through while allapps is launching, or after the
    // view has detached (it's possible for this to happen if the view is removed mid touch).
    if (v.getWindowToken() == null) {
        return;
    }

    if (!mWorkspace.isFinishedSwitchingState()) {
        return;
    }

    Object tag = v.getTag();
    if (tag instanceof ShortcutInfo) {
        // Open shortcut
        final Intent intent = ((ShortcutInfo) tag).intent;
        int[] pos = new int[2];
        v.getLocationOnScreen(pos);
        intent.setSourceBounds(new Rect(pos[0], pos[1],
                pos[0] + v.getWidth(), pos[1] + v.getHeight()));

        boolean success = startActivitySafely(v, intent, tag);

        if (success && v instanceof BubbleTextView) {
            mWaitingForResume = (BubbleTextView) v;
            mWaitingForResume.setStayPressed(true);
        }
    } else if (tag instanceof FolderInfo) {
        if (v instanceof FolderIcon) {
            FolderIcon fi = (FolderIcon) v;
            handleFolderClick(fi);
        }
    } else if (v == mAllAppsButton) {
        if (isAllAppsVisible()) {
            showWorkspace(true);
        } else {
            onClickAllAppsButton(v);
        }
    }
}
           

接着啟動應用圖示對應的應用的Activity。

boolean startActivitySafely(View v, Intent intent, Object tag) {
    boolean success = false;
    try {
        success = startActivity(v, intent, tag);
    } catch (ActivityNotFoundException e) {
        Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
        Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);
    }
    return success;
}
           

看 startActivity(v, intent, tag)。

boolean startActivity(View v, Intent intent, Object tag) {
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

    try {
        // Only launch using the new animation if the shortcut has not opted out (this is a
        // private contract between launcher and may be ignored in the future).
        boolean useLaunchAnimation = (v != null) &&
                !intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION);
        UserHandle user = (UserHandle) intent.getParcelableExtra(ApplicationInfo.EXTRA_PROFILE);
        LauncherApps launcherApps = (LauncherApps)
                this.getSystemService(Context.LAUNCHER_APPS_SERVICE);
        if (useLaunchAnimation) {
            ActivityOptions opts = ActivityOptions.makeScaleUpAnimation(v, 0, 0,
                    v.getMeasuredWidth(), v.getMeasuredHeight());
            if (user == null || user.equals(android.os.Process.myUserHandle())) {
                // Could be launching some bookkeeping activity
                startActivity(intent, opts.toBundle());
            } else {
                launcherApps.startMainActivity(intent.getComponent(), user,
                        intent.getSourceBounds(),
                        opts.toBundle());
            }
        } else {
            if (user == null || user.equals(android.os.Process.myUserHandle())) {
                startActivity(intent);
            } else {
                launcherApps.startMainActivity(intent.getComponent(), user,
                        intent.getSourceBounds(), null);
            }
        }
        return true;
    } catch (SecurityException e) {
        Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
        Log.e(TAG, "Launcher does not have the permission to launch " + intent +
                ". Make sure to create a MAIN intent-filter for the corresponding activity " +
                "or use the exported attribute for this activity. "
                + "tag="+ tag + " intent=" + intent, e);
    }
    return false;
}
           

        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK),将Activity元件的啟動标志位Intent.FLAG_ACTIVITY_NEW_TASK設定為1,以便它可以在一個新的任務中啟動。

2 frameworks\base\core\java\android\app\Activity.java

/**
* Same as {@link #startActivity(Intent, Bundle)} with no options
* specified.
*
* @param intent The intent to start.
*
* @throws android.content.ActivityNotFoundException
*
* @see #startActivity(Intent, Bundle)
* @see #startActivityForResult
*/
@Override
public void startActivity(Intent intent) {
    this.startActivity(intent, null);
}
           

看this.startActivity(intent, null)。

/**
* Launch a new activity.  You will not receive any information about when
* the activity exits.  This implementation overrides the base version,
* providing information about
* the activity performing the launch.  Because of this additional
* information, the {@link Intent#FLAG_ACTIVITY_NEW_TASK} launch flag is not
* required; if not specified, the new activity will be added to the
* task of the caller.
*
* <p>This method throws {@link android.content.ActivityNotFoundException}
* if there was no Activity found to run the given Intent.
*
* @param intent The intent to start.
* @param options Additional options for how the Activity should be started.
* See {@link android.content.Context#startActivity(Intent, Bundle)}
* Context.startActivity(Intent, Bundle)} for more details.
*
* @throws android.content.ActivityNotFoundException
*
* @see #startActivity(Intent)
* @see #startActivityForResult
*/
@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);
    }
}
           

先看startActivityForResult(intent, -1),其中第二個參數設定為-1表示Launcher元件不需要知道即将啟動的Activity元件的執行結果。

/**
* Same as calling {@link #startActivityForResult(Intent, int, Bundle)}
* with no options.
*
* @param intent The intent to start.
* @param requestCode If >= 0, this code will be returned in
*                    onActivityResult() when the activity exits.
*
* @throws android.content.ActivityNotFoundException
*
* @see #startActivity
*/
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {
    startActivityForResult(intent, requestCode, null);
}
           

發現最後還是會調用到三個參數的startActivityForResult方法。

/**
* Launch an activity for which you would like a result when it finished.
* When this activity exits, your
* onActivityResult() method will be called with the given requestCode.
* Using a negative requestCode is the same as calling
* {@link #startActivity} (the activity is not launched as a sub-activity).
*
* <p>Note that this method should only be used with Intent protocols
* that are defined to return a result.  In other protocols (such as
* {@link Intent#ACTION_MAIN} or {@link Intent#ACTION_VIEW}), you may
* not get the result when you expect.  For example, if the activity you
* are launching uses {@link Intent#FLAG_ACTIVITY_NEW_TASK}, it will not
* run in your task and thus you will immediately receive a cancel result.
*
* <p>As a special case, if you call startActivityForResult() with a requestCode
* >= 0 during the initial onCreate(Bundle savedInstanceState)/onResume() of your
* activity, then your window will not be displayed until a result is
* returned back from the started activity.  This is to avoid visible
* flickering when redirecting to another activity.
*
* <p>This method throws {@link android.content.ActivityNotFoundException}
* if there was no Activity found to run the given Intent.
*
* @param intent The intent to start.
* @param requestCode If >= 0, this code will be returned in
*                    onActivityResult() when the activity exits.
* @param options Additional options for how the Activity should be started.
* See {@link android.content.Context#startActivity(Intent, Bundle)}
* Context.startActivity(Intent, Bundle)} for more details.
*
* @throws android.content.ActivityNotFoundException
*
* @see #startActivity
*/
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);
        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;
        }

        cancelInputsAndStartExitTransition(options);
        // 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);
        }
    }
}
           

看mInstrumentation.execStartActivity(this, mMainThread.getApplicationThread(), mToken, this,intent, requestCode, options)。

3 frameworks\base\core\java\android\app\Instrumentation.java

        Instrumentation,能夠允許你監視應用程式和系統的所有互動。每一個應用程式隻有一個Instrumentation對象,每個Activity内都有一個對該對象的引用。Instrumentation可以了解為應用程序的管家,ActivityThread要建立或暫停某個Activity時,都需要通過Instrumentation來進行具體的操作。

/**
* Like {@link #execStartActivity(android.content.Context, android.os.IBinder,
* android.os.IBinder, String, android.content.Intent, int, android.os.Bundle)},
* but for calls from a {#link Fragment}.
*
* @param who The Context from which the activity is being started.
* @param contextThread The main thread of the Context from which the activity
*                      is being started.
* @param token Internal token identifying to the system who is starting
*              the activity; may be null.
* @param target Which element is performing the start (and thus receiving
*               any result).
* @param intent The actual Intent to start.
* @param requestCode Identifier for this request's result; less than zero
*                    if the caller is not expecting a result.
*
* @return To force the return of a particular result, return an
*         ActivityResult object containing the desired data; otherwise
*         return null.  The default implementation always returns null.
*
* @throws android.content.ActivityNotFoundException
*
* @see Activity#startActivity(Intent)
* @see Activity#startActivityForResult(Intent, int)
* @see Activity#startActivityFromChild
*
* {@hide}
*/
public ActivityResult execStartActivity(
    Context who, IBinder contextThread, IBinder token, String 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);
                ActivityResult result = null;
                if (am.ignoreMatchingSpecificIntents()) {
                    result = am.onStartActivity(intent);
                }
                if (result != null) {
                    am.mHits++;
                    return result;
                } else if (am.match(who, null, intent)) {
                    am.mHits++;
                    if (am.isBlocking()) {
                        return requestCode >= 0 ? am.getResult() : null;
                    }
                    break;
                }
            }
        }
    }
    try {
        intent.migrateExtraStreamToClipData();
        intent.prepareToLeaveProcess(who);
        int result = ActivityManager.getService()        //位置1
            .startActivity(whoThread, who.getBasePackageName(), intent,
                    intent.resolveTypeIfNeeded(who.getContentResolver()),
                    token, target, requestCode, 0, null, options);
        checkStartActivityResult(result, intent);       //位置2
    } catch (RemoteException e) {
        throw new RuntimeException("Failure from system", e);
    }
    return null;
}
           

位置1 ActivityManager.getService().startActivity,會通過aidl跨程序調用ActivityManagerService的startActivity。

位置2 checkStartActivityResult(result, intent),這裡會對啟動Activity的結果傳回做一個檢查判斷,抛出異常。

/** @hide */
public static void checkStartActivityResult(int res, Object intent) {
    if (!ActivityManager.isStartResultFatalError(res)) {
        return;
    }

    switch (res) {
        case ActivityManager.START_INTENT_NOT_RESOLVED:
        case ActivityManager.START_CLASS_NOT_FOUND:
            if (intent instanceof Intent && ((Intent)intent).getComponent() != null)
                throw new ActivityNotFoundException(
                        "Unable to find explicit activity class "
                        + ((Intent)intent).getComponent().toShortString()
                        + "; have you declared this activity in your AndroidManifest.xml?");
            throw new ActivityNotFoundException(
                    "No Activity found to handle " + intent);
        case ActivityManager.START_PERMISSION_DENIED:
            throw new SecurityException("Not allowed to start activity "
                    + intent);
        case ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:
            throw new AndroidRuntimeException(
                    "FORWARD_RESULT_FLAG used while also requesting a result");
        case ActivityManager.START_NOT_ACTIVITY:
            throw new IllegalArgumentException(
                    "PendingIntent is not an activity");
        case ActivityManager.START_NOT_VOICE_COMPATIBLE:
            throw new SecurityException(
                    "Starting under voice control not allowed for: " + intent);
        case ActivityManager.START_VOICE_NOT_ACTIVE_SESSION:
            throw new IllegalStateException(
                    "Session calling startVoiceActivity does not match active session");
        case ActivityManager.START_VOICE_HIDDEN_SESSION:
            throw new IllegalStateException(
                    "Cannot start voice activity on a hidden session");
        case ActivityManager.START_ASSISTANT_NOT_ACTIVE_SESSION:
            throw new IllegalStateException(
                    "Session calling startAssistantActivity does not match active session");
        case ActivityManager.START_ASSISTANT_HIDDEN_SESSION:
            throw new IllegalStateException(
                    "Cannot start assistant activity on a hidden session");
        case ActivityManager.START_CANCELED:
            throw new AndroidRuntimeException("Activity could not be started for "
                    + intent);
        default:
            throw new AndroidRuntimeException("Unknown error code "
                    + res + " when starting " + intent);
    }
}
           

4 frameworks/base/core/java/android/app/ActivityManager.java

接着注釋1往下看。

/**
* @hide
*/
public static IActivityManager getService() {
    return IActivityManagerSingleton.get();
}
           
private static final Singleton<IActivityManager> IActivityManagerSingleton =
        new Singleton<IActivityManager>() {
    @Override
    protected IActivityManager create() {
        final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
        final IActivityManager am = IActivityManager.Stub.asInterface(b);
        return am;
    }
};
        
           

通過ServiceManager來擷取Context.ACTIVITY_SERVICE的服務。

5 frameworks/base/core/java/android/util/Singleton.java

/**
* Singleton helper class for lazily initialization.
*
* Modeled after frameworks/base/include/utils/Singleton.h
*
* @hide
*/
public abstract class Singleton<T> {
    private T mInstance;

    protected abstract T create();

    public final T get() {
        synchronized (this) {
            if (mInstance == null) {
                mInstance = create();
            }
            return mInstance;
        }
    }
}
           

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

ActivityManager通過跨程序方式調用到ActivityManagerService。

        ActivityManagerService,服務端對象,負責系統中所有Activity的生命周期。也是Android中最核心的服務,主要負責系統中四大元件的啟動、切換、排程及應用程式的管理和排程等工作。它運作在System系統程序中。

@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) {
    return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
            resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
            true /*validateIncomingUser*/);
}

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,
        boolean validateIncomingUser) {
    enforceNotIsolatedCaller("startActivity");

    userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser,
            Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");

    // TODO: Switch to user app stacks here.
    return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
            .setCaller(caller)
            .setCallingPackage(callingPackage)
            .setResolvedType(resolvedType)
            .setResultTo(resultTo)
            .setResultWho(resultWho)
            .setRequestCode(requestCode)
            .setStartFlags(startFlags)
            .setProfilerInfo(profilerInfo)
            .setActivityOptions(bOptions)
            .setMayWait(userId)
            .execute();

}
           

Android O以及之前是直接調用到ActivityStarter,Android P會通過ActivityStartController來調用ActivityStarter。

7 frameworks/base/services/core/java/com/android/server/am/ActivityStartController.java

/**
* @return A starter to configure and execute starting an activity. It is valid until after
*         {@link ActivityStarter#execute} is invoked. At that point, the starter should be
*         considered invalid and no longer modified or used.
*/
ActivityStarter obtainStarter(Intent intent, String reason) {
    return mFactory.obtain().setIntent(intent).setReason(reason);
}
           

8 frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java

        ActivityStarter,Activity啟動的控制器,處理Intent與Flag對Activity啟動的影響,具體說來有: 尋找符合啟動條件的Activity,如果有多個,讓使用者選擇; 校驗啟動參數的合法性; 傳回int參數,代表Activity啟動是否成功。

       Factory是ActivityStarter的内部類。

/**
* An interface that to provide {@link ActivityStarter} instances to the controller. This is
* used by tests to inject their own starter implementations for verification purposes.
*/
@VisibleForTesting
interface Factory {
    /**
    * Sets the {@link ActivityStartController} to be passed to {@link ActivityStarter}.
    */
    void setController(ActivityStartController controller);

    /**
    * Generates an {@link ActivityStarter} that is ready to handle a new start request.
    * @param controller The {@link ActivityStartController} which the starter who will own
    *                   this instance.
    * @return an {@link ActivityStarter}
    */
    ActivityStarter obtain();

    /**
    * Recycles a starter for reuse.
    */
    void recycle(ActivityStarter starter);
}
           

DefaultFactory實作了Factory這個接口。

/**
* Default implementation of {@link StarterFactory}.
*/
static class DefaultFactory implements Factory {
    /**
    * The maximum count of starters that should be active at one time:
    * 1. last ran starter (for logging and post activity processing)
    * 2. current running starter
    * 3. starter from re-entry in (2)
    */
    private final int MAX_STARTER_COUNT = 3;

    private ActivityStartController mController;
    private ActivityManagerService mService;
    private ActivityStackSupervisor mSupervisor;
    private ActivityStartInterceptor mInterceptor;

    private SynchronizedPool<ActivityStarter> mStarterPool =
            new SynchronizedPool<>(MAX_STARTER_COUNT);

    ...
    @Override
    public ActivityStarter obtain() {
        ActivityStarter starter = mStarterPool.acquire();

        if (starter == null) {
            starter = new ActivityStarter(mController, mService, mSupervisor, mInterceptor);
        }

        return starter;
    }
    ...
}
           

接着看mActivityStartController.obtainStarter調用的execute。

/**
* Starts an activity based on the request parameters provided earlier.
* @return The starter result.
*/
int execute() {
    try {
        // TODO(b/64750076): Look into passing request directly to these methods to allow
        // for transactional diffs and preprocessing.
        if (mRequest.mayWait) {
            return startActivityMayWait(mRequest.caller, mRequest.callingUid,
                    mRequest.callingPackage, mRequest.intent, mRequest.resolvedType,
                    mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
                    mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
                    mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
                    mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
                    mRequest.inTask, mRequest.reason,
                    mRequest.allowPendingRemoteAnimationRegistryLookup);
        } else {
            return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
                    mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
                    mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
                    mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
                    mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
                    mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
                    mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
                    mRequest.outActivity, mRequest.inTask, mRequest.reason,
                    mRequest.allowPendingRemoteAnimationRegistryLookup);
        }
    } finally {
        onExecutionComplete();
    }
}
           

        由于在調用execute之前調用過setMayWait,是以mRequest.mayWait為true。看startActivityMayWait。

        ActivityStarter.startActivityMayWait方法中調用多個startActivity方法後會調用到方法startActivityUnchecked。這個方法裡會根據啟動标志位和Activity啟動模式來決定如何啟動一個Activity以及是否要調用deliverNewIntent方法通知Activity,有一個Intent試圖重新啟動它。

private 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, SafeActivityOptions options, boolean ignoreTargetSecurity,
        int userId, TaskRecord inTask, String reason,
        boolean allowPendingRemoteAnimationRegistryLookup) {

    ...
    synchronized (mService) {
        final ActivityStack stack = mSupervisor.mFocusedStack;
        stack.mConfigWillChange = globalConfig != null
                && mService.getGlobalConfiguration().diff(globalConfig) != 0;
        if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
                "Starting activity when config will change = " + stack.mConfigWillChange);

        ...
        //記錄Activity的資料
        final ActivityRecord[] outRecord = new ActivityRecord[1];
        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);

            Binder.restoreCallingIdentity(origId);
            ...

        mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outRecord[0]);
        return res;
    }
}
           

接着看startActivity。

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,
        SafeActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
        ActivityRecord[] outActivity, TaskRecord inTask, String reason,
        boolean allowPendingRemoteAnimationRegistryLookup) {

    if (TextUtils.isEmpty(reason)) {
        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,
            inTask, allowPendingRemoteAnimationRegistryLookup);

    if (outActivity != null) {
        // mLastStartActivityRecord[0] is set in the call to startActivity above.
        outActivity[0] = mLastStartActivityRecord[0];
    }

    return getExternalResult(mLastStartActivityResult);
}
           

接着看startActivity。

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,
        SafeActivityOptions options,
        boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
        TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup) {
    ...
    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;
    }

    if (r.appTimeTracker == null && sourceRecord != null) {
        // If the caller didn't specify an explicit time tracker, we want to continue
        // tracking under any it has.
        r.appTimeTracker = sourceRecord.appTimeTracker;
    }

    final ActivityStack stack = mSupervisor.mFocusedStack;

    // If we are starting an activity that is not from the same uid as the currently resumed
    // one, check whether app switches are allowed.
    if (voiceSession == null && (stack.getResumedActivity() == null
            || stack.getResumedActivity().info.applicationInfo.uid != realCallingUid)) {
        if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
                realCallingPid, realCallingUid, "Activity start")) {
            mController.addPendingActivityLaunch(new PendingActivityLaunch(r,
                    sourceRecord, startFlags, stack, callerApp));
            ActivityOptions.abort(checkedOptions);
            return ActivityManager.START_SWITCHES_CANCELED;
        }
    }

    if (mService.mDidAppSwitch) {
        // This is the second allowed switch since we stopped switches,
        // so now just generally allow switches.  Use case: user presses
        // home (switches disabled, switch to home, mDidAppSwitch now true);
        // user taps a home icon (coming from home so allowed, we hit here
        // and now allow anyone to switch again).
        mService.mAppSwitchesAllowedTime = 0;
    } else {
        mService.mDidAppSwitch = true;
    }

    mController.doPendingActivityLaunches(false);

    return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
            true /* doResume */, checkedOptions, inTask, outActivity);
}

           

接着 看startActivity。

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.
        //擷取Activity的任務棧
        final ActivityStack stack = mStartActivity.getStack();
        if (!ActivityManager.isStartResultSuccessful(result) && stack != null) {
            stack.finishActivityLocked(mStartActivity, RESULT_CANCELED,
                    null /* intentResultData */, "startActivity", true /* oomAdj */);
        }
        mService.mWindowManager.continueSurfaceLayout();
    }

    postStartActivityProcessing(r, result, mTargetStack);

    return result;
}
           

再看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) {

    ...

    // If the activity being launched is the same as the one currently at the top, then
    // we need to check if it should only be launched once.
    final ActivityStack topStack = mSupervisor.mFocusedStack;
    final ActivityRecord topFocused = topStack.getTopActivity();
    final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);
    final boolean dontStart = top != null && mStartActivity.resultTo == null
            && top.realActivity.equals(mStartActivity.realActivity)
            && top.userId == mStartActivity.userId
            && top.app != null && top.app.thread != null
            && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
            || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK));
    ...

    mService.grantUriPermissionFromIntentLocked(mCallingUid, mStartActivity.packageName,
            mIntent, mStartActivity.getUriPermissionsLocked(), mStartActivity.userId);
    mService.grantEphemeralAccessLocked(mStartActivity.userId, mIntent,
            mStartActivity.appInfo.uid, UserHandle.getAppId(mCallingUid));
    if (newTask) {
        EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, mStartActivity.userId,
                mStartActivity.getTask().taskId);
    }
    ActivityStack.logStartActivity(
            EventLogTags.AM_CREATE_ACTIVITY, mStartActivity, mStartActivity.getTask());
    mTargetStack.mLastPausedActivity = null;

    mSupervisor.sendPowerHintForLaunchStartIfNeeded(false /* forceSend */, mStartActivity);

    mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
            mOptions);
    if (mDoResume) {
        final ActivityRecord topTaskActivity =
                mStartActivity.getTask().topRunningActivityLocked();
        if (!mTargetStack.isFocusable()
                || (topTaskActivity != null && topTaskActivity.mTaskOverlay
                && mStartActivity != topTaskActivity)) {
            // If the activity is not focusable, we can't resume it, but still would like to
            // make sure it becomes visible as it starts (this will also trigger entry
            // animation). An example of this are PIP activities.
            // Also, we don't want to resume activities in a task that currently has an overlay
            // as the starting activity just needs to be in the visible paused state until the
            // over is removed.
            mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
            // Go ahead and tell window manager to execute app transition for this activity
            // since the app transition will not be triggered through the resume channel.
            mService.mWindowManager.executeAppTransition();
        } else {
            // If the target stack was not previously focusable (previous top running activity
            // on that stack was not visible) then any prior calls to move the stack to the
            // will not update the focused stack.  If starting the new activity now allows the
            // task stack to be focusable, then ensure that we now update the focused stack
            // accordingly.
            if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) {
                mTargetStack.moveToFront("startActivityUnchecked");
            }
            mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
                    mOptions);
        }
    } else if (mStartActivity != null) {
        mSupervisor.mRecentTasks.add(mStartActivity.getTask());
    }
    mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);

    mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTask(), preferredWindowingMode,
            preferredLaunchDisplayId, mTargetStack);

    return START_SUCCESS;
}
           

看調用ActivityStackSupervisor的 resumeFocusedStackTopActivityLocked 方法。

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

        ActivityStackSupervisor負責所有Activity棧的管理,内部管理了mHomeStack、mFocusedStack和mLastFocusedStack三個Activity棧。其中,mHomeStack管理的是Launcher相關的Activity棧;mFocusedStack管理的是目前顯示在前台Activity的Activity棧;mLastFocusedStack管理的是上一次顯示在前台Activity的Activity棧。

boolean resumeFocusedStackTopActivityLocked() {
    return resumeFocusedStackTopActivityLocked(null, null, null);
}

boolean resumeFocusedStackTopActivityLocked(
        ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {

    if (!readyToResume()) {
        return false;
    }

    if (targetStack != null && isFocusedStack(targetStack)) {
        //位置1
        return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
    }

    final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
    if (r == null || !r.isState(RESUMED)) {
        mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
    } else if (r.isState(RESUMED)) {
        // Kick off any lingering app transitions form the MoveTaskToFront operation.
        mFocusedStack.executeAppTransition(targetOptions);
    }

    return false;
}
           

        傳過來的參數,targetStack對應的是ActivityStack對象,不為null,isFocusedStack(targetStack)判斷為true,是以判斷條件進入位置1處執行resumeTopActivityUncheckedLocked方法。

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

ActivityStack,Activity在AMS的棧管理,用來記錄已經啟動的Activity的先後關系,狀态資訊等。通過ActivityStack決定是否需要啟動新的程序。

/**
* Ensure that the top activity in the stack is resumed.
*
* @param prev The previously resumed activity, for when in the process
* of pausing; can be null to call from elsewhere.
* @param options Activity options.
*
* @return Returns true if something is being resumed, or false if
* nothing happened.
*
* NOTE: It is not safe to call this method directly as it can cause an activity in a
*       non-focused stack to be resumed.
*       Use {@link ActivityStackSupervisor#resumeFocusedStackTopActivityLocked} to resume the
*       right activity for the current system state.
*/
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;
        //位置1
        result = resumeTopActivityInnerLocked(prev, options);
    } finally {
        mStackSupervisor.inResumeTopActivity = false;
    }

    // When resuming the top activity, it may be necessary to pause the top activity (for
    // example, returning to the lock screen. We suppress the normal pause logic in
    // {@link #resumeTopActivityUncheckedLocked}, since the top activity is resumed at the end.
    // We call the {@link ActivityStackSupervisor#checkReadyForSleepLocked} again here to ensure
    // any necessary pause logic occurs. In the case where the Activity will be shown regardless
    // of the lock screen, the call to {@link ActivityStackSupervisor#checkReadyForSleepLocked}
    // is skipped.
    final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
    if (next == null || !next.canTurnScreenOn()) {
        checkReadyForSleep();
    }

    return result;
}
           

繼續看位置1處的resumeTopActivityInnerLocked方法。

@GuardedBy("mService")
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
    ...
                mStackSupervisor.startSpecificActivityLocked(next, true, false);
                if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
                return true;
    ...      
}
           

         在ActivityStack.resumeTopActivityInnerLocked方法中會去判斷是否有Activity處于Resume狀态,如果有的話會先讓這個Activity執行Pausing過程,然後再執行startSpecificActivityLocked方法啟動要啟動Activity。

        又調用到ActivityStarterSuperVisor.java的startSpecificActivityLocked。

        在這個方法中會去根據程序和線程是否存在判斷App是否已經啟動,如果已經啟動,就會調用realStartActivityLocked方法繼續處理;如果沒有啟動則調用ActivityManagerService.startProcessLocked方法建立新的程序處理。

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

    getLaunchTimeTracker().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.longVersionCode,
                        mService.mProcessStats);
            }
            //位置1
            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);
}
           

看位置1的realStartActivityLocked(r, app, andResume, checkConfig)方法。

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
        boolean andResume, boolean checkConfig) throws RemoteException {
    ...
           // Create activity launch transaction.
            final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
                    r.appToken);
            //位置1
            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, app.repProcState, r.icicle,
                    r.persistentState, results, newIntents, mService.isNextTransitionForward(),
                    profilerInfo));

            // Set desired final state.
            final ActivityLifecycleItem lifecycleItem;
            if (andResume) {
                lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
            } else {
                lifecycleItem = PauseActivityItem.obtain();
            }
            clientTransaction.setLifecycleStateRequest(lifecycleItem);
            
            //位置2
            // Schedule transaction.
            mService.getLifecycleManager().scheduleTransaction(clientTransaction);

    ...

    return true;
}
           

       Android O是直接通過主線程來啟動Activity,Android P是通過事務機制來啟動Activity。

       在位置1 realStartActivityLocked方法中為ClientTransaction對象添加LaunchActivityItem的callback,然後設定目前的生命周期狀态;           在位置2最後調用ClientLifecycleManager.scheduleTransaction方法執行。

       先直接位置2最後調用ClientLifecycleManager.scheduleTransaction方法。

11 frameworks/base/services/core/java/com/android/server/am/ClientLifecycleManager.java

Android P在這裡引入了ClientLifecycleManager和ClientTransactionHandler來輔助管理Activity生命周期。

/**
* Schedule a transaction, which may consist of multiple callbacks and a lifecycle request.
* @param transaction A sequence of client transaction items.
* @throws RemoteException
*
* @see ClientTransaction
*/
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
    final IApplicationThread client = transaction.getClient();
    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對象的方法。

12 frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java

/**
* Schedule the transaction after it was initialized. It will be send to client and all its
* individual parts will be applied in the following sequence:
* 1. The client calls {@link #preExecute(ClientTransactionHandler)}, which triggers all work
*    that needs to be done before actually scheduling the transaction for callbacks and
*    lifecycle state request.
* 2. The transaction message is scheduled.
* 3. The client calls {@link TransactionExecutor#execute(ClientTransaction)}, which executes
*    all callbacks and necessary lifecycle transitions.
*/
public void schedule() throws RemoteException {
    mClient.scheduleTransaction(this);
}
           

mClient對應IApplicationThread類型。ActivityThread的内部類ApplicationThread派生了這個接口并實作了對應的方法。

13 frameworks\base\core\java\android\app\ActivityThread.java

        ActivityThread,App的真正入口,當開啟App之後,會調用main()開始運作,開啟消息循環隊列,也就是UI線程或叫主線程。與ActivityManagerServices配合,一起完成Activity的管理工作。

        ApplicationThread是ActivityThread的一個内部類。 用來實作ActivityManagerService與ActivityThread之間的互動。在ActivityManagerService需要管理相關Application中的Activity的生命周期時,通過ApplicationThread的代理對象與ActivityThread通訊。

@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
    ActivityThread.this.scheduleTransaction(transaction);
}
           

ActivityThread類中并沒有定義scheduleTransaction方法,是以調用的是他父類ClientTransactionHandler的scheduleTransaction方法。

/**
* This manages the execution of the main thread in an
* application process, scheduling and executing activities,
* broadcasts, and other operations on it as the activity
* manager requests.
*
* {@hide}
*/
public final class ActivityThread extends ClientTransactionHandler {
           

14 frameworks\base\core\java\android\app\ClientTransactionHandler.java

/** Prepare and schedule transaction for execution. */
void scheduleTransaction(ClientTransaction transaction) {
    transaction.preExecute(this);
    sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
           

ActivityThread.sendMessage方法會把消息發送給内部名字叫H的Handler。

public void handleMessage(Message msg) {
        if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
        switch (msg.what) {
            ...
            case EXECUTE_TRANSACTION:
                final ClientTransaction transaction = (ClientTransaction) msg.obj;
                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;
                ...
    }
}
           

Handler H的執行個體接收到EXECUTE_TRANSACTION消息後調用TransactionExecutor.execute方法。

15 frameworks\base\core\java\android\app\servertransaction\TransactionExecutor.java

/**
* Resolve transaction.
* First all callbacks will be executed in the order they appear in the list. If a callback
* requires a certain pre- or post-execution state, the client will be transitioned accordingly.
* Then the client will cycle to the final lifecycle state if provided. Otherwise, it will
* either remain in the initial state, or last state needed by a callback.
*/
public void execute(ClientTransaction transaction) {
    final IBinder token = transaction.getActivityToken();
    log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);

    executeCallbacks(transaction);

    executeLifecycleState(transaction);
    mPendingActions.clear();
    log("End resolving transaction");
}
           

看excuteCallbacks方法。

/** Cycle through all states requested by callbacks and execute them at proper times. */
@VisibleForTesting
public void executeCallbacks(ClientTransaction transaction) {
    final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
    if (callbacks == null) {
        // No callbacks to execute, return early.
        return;
    }
    log("Resolving callbacks");

    final IBinder token = transaction.getActivityToken();
    ActivityClientRecord r = mTransactionHandler.getActivityClient(token);

    // In case when post-execution state of the last callback matches the final state requested
    // for the activity in this transaction, we won't do the last transition here and do it when
    // moving to final state instead (because it may contain additional parameters from server).
    final ActivityLifecycleItem finalStateRequest = transaction.getLifecycleStateRequest();
    final int finalState = finalStateRequest != null ? finalStateRequest.getTargetState()
                : UNDEFINED;
    // Index of the last callback that requests some post-execution state.
    final int lastCallbackRequestingState = lastCallbackRequestingState(transaction);

    final int size = callbacks.size();
    for (int i = 0; i < size; ++i) {
        final ClientTransactionItem item = callbacks.get(i);
        log("Resolving callback: " + item);
        final int postExecutionState = item.getPostExecutionState();
        final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r,
                item.getPostExecutionState());
        if (closestPreExecutionState != UNDEFINED) {
            cycleToPath(r, closestPreExecutionState);
        }

        //位置1
        item.execute(mTransactionHandler, token, mPendingActions);
        item.postExecute(mTransactionHandler, token, mPendingActions);
        if (r == null) {
            // Launch activity request will create an activity record.
            r = mTransactionHandler.getActivityClient(token);
        }

        if (postExecutionState != UNDEFINED && r != null) {
            // Skip the very last transition and perform it by explicit state request instead.
            final boolean shouldExcludeLastTransition =
                    i == lastCallbackRequestingState && finalState == postExecutionState;
            cycleToPath(r, postExecutionState, shouldExcludeLastTransition);
        }
    }
}
           

item.execute的item對應ClientTransactionItem對象。

16 frameworks\base\core\java\android\app\servertransaction\ClientTransactionItem.java

ClientTransactionItem 作為系統與用戶端(APP)的回調,比如Activity配置變化、多視窗模式改變、Activity的啟動等。

/**
* A callback message to a client that can be scheduled and executed.
* Examples of these might be activity configuration change, multi-window mode change, activity
* result delivery etc.
*
* @see ClientTransaction
* @see com.android.server.am.ClientLifecycleManager
* @hide
*/
public abstract class ClientTransactionItem implements BaseClientRequest, Parcelable {

    /** Get the state that must follow this callback. */
    @LifecycleState
    public int getPostExecutionState() {
        return UNDEFINED;
    }


    // Parcelable

    @Override
    public int describeContents() {
        return 0;
    }
}
           

由于ClientTransactionItem.java隻是一個抽象類,是以要找到其實作類看它具體的實作。

17 frameworks\base\core\java\android\app\servertransaction\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);
    client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
    Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
           

看client.handleLaunchActivity方法,client對應ClientTransactionHandler對象。ClientTransactionHandler是個抽象類。需要找到它的實作類。

18 frameworks\base\core\java\android\app\ClientTransactionHandler.java

/** Perform activity launch. */
public abstract Activity handleLaunchActivity(ActivityThread.ActivityClientRecord r,
        PendingTransactionActions pendingActions, Intent customIntent);
           

19 frameworks\base\core\java\android\app\ActivityThread.java

/**
* Extended implementation of activity launch. Used when server requests a launch or relaunch.
*/
@Override
public Activity handleLaunchActivity(ActivityClientRecord r,
        PendingTransactionActions pendingActions, 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);

    // Initialize before creating the activity
    if (!ThreadedRenderer.sRendererDisabled) {
        GraphicsEnvironment.earlyInitEGL();
    }
    WindowManagerGlobal.initialize();

    //位置1
    final Activity a = performLaunchActivity(r, customIntent);

    if (a != null) {
        r.createdConfig = new Configuration(mConfiguration);
        reportSizeConfigurations(r);
        if (!r.activity.mFinished && pendingActions != null) {
            pendingActions.setOldState(r.state);
            pendingActions.setRestoreInstanceState(true);
            pendingActions.setCallOnPostCreate(true);
        }
    } 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();
        }
    }

    return a;
}
           

看位置1的performLaunchActivity方法。

/**  Core implementation of activity launch. */
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    ...
    ContextImpl appContext = createBaseContextForActivity(r);
    Activity activity = null;
    try {
        //用類加載器來建立Activity的執行個體
        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);
            ...
            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 (r.isPersistable()) {
                //位置1
                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.setState(ON_CREATE);

        mActivities.put(r.token, r);
    ...
    return activity;
}
           

  看位置1的mInstrumentation.callActivityOnCreate方法。

  20 frameworks\base\core\java\android\app\Instrumentation.java

/**
* Perform calling of an activity's {@link Activity#onCreate}
* method.  The default implementation simply calls through to that method.
*  @param activity The activity being created.
* @param icicle The previously frozen state (or null) to pass through to
* @param persistentState The previously persisted state (or null)
*/
public void callActivityOnCreate(Activity activity, Bundle icicle,
        PersistableBundle persistentState) {
    prePerformCreate(activity);
    activity.performCreate(icicle, persistentState);
    postPerformCreate(activity);
}
           

看activity.performCreate方法。

21 frameworks/base/core/java/android/app/Activity.java

final void performCreate(Bundle icicle, PersistableBundle persistentState) {
    mCanEnterPictureInPicture = true;
    restoreHasCurrentPermissionRequest(icicle);
    if (persistentState != null) {
        onCreate(icicle, persistentState);
    } else {
        onCreate(icicle);
    }
    writeEventLog(LOG_AM_ON_CREATE_CALLED, "performCreate");
    mActivityTransitionState.readState(icicle);

    mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(
            com.android.internal.R.styleable.Window_windowNoDisplay, false);
    mFragments.dispatchActivityCreated();
    mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
}
           

到這裡就調到Activity的onCreate方法了。

四 總結

關鍵類的作用

Launcher.apk: 本質上也是一個應用程式,運作在自己的程序中,我們看到的桌面就是 Launcher 中的一個 Activity,即Launcher.java,繼承了Activity。

Instrumentation:   能夠允許你監視應用程式和系統的所有互動。每一個應用程式隻有一個Instrumentation對象,每個Activity内都有一個對該對象的引用。Instrumentation可以了解為應用程序的管家,ActivityThread要建立或者暫停某個Activity時,是通過這個"管家"進行的,設定這個管家的好處是可以統計所有的"開銷",開銷的資訊儲存在"管家"那裡。Instrumentation和ActivityThread的分工也有本質差別,ActivityThread就像是這個家裡的主人,負責建立這個"家庭",并負責和外界打交道,比如接收AMS的通知等。

ActivityManagerServices:服務端對象,負責系統中所有Activity的生命周期。也是Android中最核心的服務,主要負責系統中四大元件的啟動、切換、排程及應用程式的管理和排程等工作。

 ActivityStarter:  Activity啟動的控制器,處理Intent與Flag對Activity啟動的影響,具體說來有: 尋找符合啟動條件的Activity,如果有多個,讓使用者選擇; 校驗啟動參數的合法性; 傳回int參數,代表Activity啟動是否成功。

 ActivityStackSupervisor:  負責所有Activity棧的管理,内部管理了mHomeStack、mFocusedStack和mLastFocusedStack三個Activity棧。其中,mHomeStack管理的是Launcher相關的Activity棧;mFocusedStack管理的是目前顯示在前台Activity的Activity棧;mLastFocusedStack管理的是上一次顯示在前台Activity的Activity棧。

ActivityStack:  Activity在AMS的棧管理,用來記錄已經啟動的Activity的先後關系,狀态資訊等。通過ActivityStack決定是否需要啟動新的程序。

ActivityThread:  App的真正入口,當開啟App之後,會調用main()開始運作,開啟消息循環隊列,也就是UI線程或叫主線程。與ActivityManagerServices配合,一起完成Activity的管理工作。

ApplicationThread:   用來實作ActivityManagerService與ActivityThread之間的互動。在ActivityManagerService需要管理相關Application中的Activity的生命周期時,通過ApplicationThread的代理對象與ActivityThread通訊。

ActivityRecord:  ActivityStack的管理對象,每個Activity在AMS對應一個ActivityRecord,來記錄Activity的狀态以及其它的管理資訊。其實就是伺服器端Activity對象的映像。

TaskRecord:AMS抽象出來的一個“任務”的概念,是記錄ActivityRecord的棧,一個“Task”包含若幹個ActivityRecord。AMS用TaskRecord確定Activity啟動和退出的順序。