Android10_原理機制系列_AMS(ATMS)之應用的第一次啓動的過程

概述

該篇基於Android 10的代碼。在 AMS之AMS的啓動---Android Framework(Android 10) 中已經介紹了,在Android 10中,activity的調度和管理已經從AMS移到了ActivityTaskManagerService中(這裏簡稱ATMS),這在下面關於應用第一次的啓動的過程當中也能清楚看到。
這個詳細過程有點複雜,因此可能有不許確的地方歡迎指出交流。html

應用的啓動過程有點複雜,該部分簡單概述下。
第二部分是跟着代碼流程一步一步看的。這裏涉及屢次跨進程,Binder大體瞭解下是什麼,能夠參考 Binder機制
第三部分「附上調用棧」,有助於查看源碼以及理解, 這個方法很好用的。

java

啓動過程總結

  1. Launcher點擊應用圖標:這個過程是Launcher進程中進行的,去啓動應用的第一個activity。
  2. 經過binder進入ATMS:在ATMS中,爲應用的第一個activity建立了ActivityRecord,找到其ActivityStack,將ActivityRecord插入到所在的TaskRecord的合適位置。最後執行到ActivityManagerInternal::startProcess
  3. 進入AMS,請求建立應用進程:這個過程建立了ProcessRecord對象並處理保存了進程所需的各類信息。最後經過Process.start()請求建立應用進程。
  4. Zygote建立應用進程:經過socket與zygote進程通訊,fork出應用進程。
  5. 應用進程主線程-執行ActivityThread的main():在應用主線程中,執行ActivityThread的main()。
  6. 進入系統進程,綁定應用進程:建立了應用的Application,將應用進程綁定到ATMS中,由它們管理。
  7. 回到應用進程:這裏主要是建立出應用第一個Activity,並執行了attach()和onCreate()。

注:AMS和ATMS服務都是在系統進程-system server進程中。
因此,整個過程 進程變化是:Launcher進程(binder)->systemserver進程(socket)->zygote進程(socket)->應用進程(binder)->systemserver進程(binder)->應用進程。

node

Activity的啓動過程詳述

下面部分代碼添加了註釋,閱讀源碼時查看下本來英文註釋是頗有用的。
在最後部分「附上調用棧」,附上了部分調用棧的過程,更有助於查看和理解,這個方法很好用的。android

這個根據理解畫的下面流程的一個簡單圖示,供參考:
ams_app_launcherapp

Launcher點擊應用圖標

Launcher點擊圖標,BaseDraggingActivity.java中startActivitySafely()調用了startActivity()。
這是的activity是Launcher的activity,在Launcher的進程中。less

Activity中各類startActivity()調用,最終都是走到的startActivityForResult(@RequiresPermission Intent intent, int requestCode, @Nullable Bundle options)方法的。socket

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

@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
    if (options != null) {
        startActivityForResult(intent, -1, options);
    } else {
        // Note we want to go through this call for compatibility with
        // applications that may have overridden the method.
        startActivityForResult(intent, -1);
    }
}

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {
    startActivityForResult(intent, requestCode, null);
}

因此Launcher點擊圖標後這裏直接從startActivityForResult()開始看,從上面能夠看到requestCode值爲-1ide

//Activity.java:
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
        @Nullable Bundle options) {
    //mParent通常爲null
    if (mParent == null) {
        options = transferSpringboardActivityOptions(options);
        //調用mInstrumentation.execStartActivity()
        //mMainThread、mInstrumentation、mToken在attach()被賦值
        Instrumentation.ActivityResult ar =
            mInstrumentation.execStartActivity(
                this, mMainThread.getApplicationThread(), mToken, this,
                intent, requestCode, options);
        ......
    } else {
        //調用mParent.startActivityFromChild(),和上面邏輯相似
    }
}

目前仍是在Launcher進程,這裏mMainThread、mInstrumentation、mToken都是在attach()被賦值。
Instrumentation監控system(主要是AM,Activity Manager)與application之間的全部交互。
mToken是IBinder對象,是Binder代理,是Android中IPC重要部分。
mMainThread是ActivityThread對象,應用的主線程。這裏是Launhcer的主線程。
那麼何時被賦值的呢?attach()在哪被調用的?看到最後就知道了^v^函數

這裏關鍵代碼 調用了mInstrumentation.execStartActivity()oop

//Instrumentation.java
@UnsupportedAppUsage
public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options) {
    IApplicationThread whoThread = (IApplicationThread) contextThread;
    ......
    try {
        intent.migrateExtraStreamToClipData();
        intent.prepareToLeaveProcess(who);
        int result = ActivityTaskManager.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;
}

這裏主要看ActivityTaskManager.getService().startActivity()這個方法。
ActivityTaskManager.getService()這個涉及Binder機制,能夠參考 Binder機制 。 這裏獲取的服務名是Context.ACTIVITY_TASK_SERVICE(=activity_task),最終調用的是ActivityTaskManagerService.startActivity()方法。

進入ATMS

經過Binder機制,由Launcher進程進入到ATMS。
ActivityTaskManagerService中的startActivity()

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

    @Override
public 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*/);
}

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

}

ATMS中的startActivity(),最終調用了ActivityStarter中的execute()。

//ActivityStarter.java:
ActivityStarter setMayWait(int userId) {
    mRequest.mayWait = true;
    mRequest.userId = userId;
    return this;
}

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.realCallingPid, mRequest.realCallingUid,
                    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,
                    mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
        } else {
            ......
        }
    } finally {
        onExecutionComplete();
    }
}

在setMayWait()中,mRequest.mayWait = true;,所以走到startActivityMayWait()。

//ActivityStarter.java:
private int startActivityMayWait(IApplicationThread caller, int callingUid,
        String callingPackage, int requestRealCallingPid, int requestRealCallingUid,
        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,
        PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
    ......
    ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
    synchronized (mService.mGlobalLock) {
        final ActivityStack stack = mRootActivityContainer.getTopDisplayFocusedStack();
        ......
        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, originatingPendingIntent,
                allowBackgroundActivityStart);
        ......
        mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outRecord[0]);
        if (outResult != null) {
            outResult.result = res;
            final ActivityRecord r = outRecord[0];
            ......
        }
        return res;
    }
}

//startActivity 1
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,
        PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {

    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, originatingPendingIntent,
            allowBackgroundActivityStart);

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

    return getExternalResult(mLastStartActivityResult);
}

//startActivity 2
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,
        PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
    .......
    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;
    }
    ......
    final ActivityStack stack = mRootActivityContainer.getTopDisplayFocusedStack();
    ......
    final int res = startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
            true /* doResume */, checkedOptions, inTask, outActivity, restrictedBgActivity);
    mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outActivity[0]);
    return res;
}

這裏主要的代碼關注:startActivityMayWait()->startActivity()->startActivity()->startActivity()
這裏3個startActivity()的同名方法,參數是不同的。參數不少得注意點看。 這幾個方法內容都不少,這裏主要注意幾個地方:

  • ActivityRecord在對應一個activity,是activity的信息記錄管理的類。這在 AMS之AMS的啓動 都是提到過的。
  • startActivityMayWait()方法中new的ActivityRecord對象 outRecord[0],在第二個startActivity()中被賦值,指向的建立的ActivityRecord對象r。

-----這裏在第二個startActivity()中建立了應用第一個activity的ActivityRecord對象

第二個startActivity()一樣調用了startActivity(),也是ActivityStarter最後一個同名startActivity方法,這裏標記爲第三個startActivity()。

//ActivityStarter.java:
//第三個:startActivity 3
private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity, boolean restrictedBgActivity) {
    int result = START_CANCELED;
    final ActivityStack startedActivityStack;
    try {
        mService.mWindowManager.deferSurfaceLayout();
        result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                startFlags, doResume, options, inTask, outActivity, restrictedBgActivity);
    } finally {
        final ActivityStack currentStack = r.getActivityStack();
        startedActivityStack = currentStack != null ? currentStack : mTargetStack;
        ......      
    }
    ......
    return result;
}

第三個startActivity()中獲取Activity所在的ActivityStack - startedActivityStack。

這裏看下startActivityUnchecked()。

//ActivityStarter.java:
// 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) {
    ......
    mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
            mOptions);
    if (mDoResume) {
        final ActivityRecord topTaskActivity =
                mStartActivity.getTaskRecord().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(mStartActivity, 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.
            mTargetStack.getDisplay().mDisplayContent.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()
                    && !mRootActivityContainer.isTopDisplayFocusedStack(mTargetStack)) {
                mTargetStack.moveToFront("startActivityUnchecked");
            }
            mRootActivityContainer.resumeFocusedStacksTopActivities(
                    mTargetStack, mStartActivity, mOptions);
        }
    } else if (mStartActivity != null) {
        mSupervisor.mRecentTasks.add(mStartActivity.getTaskRecord());
    }
    mRootActivityContainer.updateUserStack(mStartActivity.mUserId, mTargetStack);

    mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTaskRecord(),
            preferredWindowingMode, mPreferredDisplayId, mTargetStack);

    return START_SUCCESS;
}
  • startActivityUnchecked()找到目標ActivityStack - mTargetStack,而後調用了mTargetStack.startActivityLocked()找到所在TaskRecord,並將activity插入到合適位置。 這樣activity對應ActivityRecord就加入到對應ActivityStack中的對應的TaskRecord中了。
  • mRootActivityContainer.resumeFocusedStacksTopActivities();獲取棧頂activity並恢復,即將設置成resume狀態。

這裏看下這兩個方法
1. startActivityLocked()

//ActivityStack.java:
void startActivityLocked(ActivityRecord r, ActivityRecord focusedTopActivity,
        boolean newTask, boolean keepCurTransition, ActivityOptions options) {
    TaskRecord rTask = r.getTaskRecord();
    final int taskId = rTask.taskId;
    final boolean allowMoveToFront = options == null || !options.getAvoidMoveToFront();
    // mLaunchTaskBehind tasks get placed at the back of the task stack.
    if (!r.mLaunchTaskBehind && allowMoveToFront
            && (taskForIdLocked(taskId) == null || newTask)) {
        // Last activity in task had been removed or ActivityManagerService is reusing task.
        // Insert or replace.
        // Might not even be in.
        insertTaskAtTop(rTask, r);
    }
    TaskRecord task = null;
    ......
    task = activityTask;
    ......
    task.setFrontOfTask();

    // The transition animation and starting window are not needed if {@code allowMoveToFront}
    // is false, because the activity won't be visible.
    if ((!isHomeOrRecentsStack() || numActivities() > 0) && allowMoveToFront) {
        ......
    } else {
        // If this is the first activity, don't do any fancy animations,
        // because there is nothing for it to animate on top of.
        ActivityOptions.abort(options);
    }
}

這裏找到activity的TaskRecord,並將activity對應的ActivityRecord插入到TaskRecord的合適位置。而後進行過渡動畫相關判斷處理。

-----到此,應用第一個activity的ActivityRecord已建立,並找到其ActivityStack。最後在ActivityStack中將ActivityRecord插入到所在的TaskRecord的合適位置。
參考 AMS之AMS的啓動 最後面那個圖理解下,ActivityStack、ActivityStackSupervisor、TaskRecord、ActivityRecord、ProcessRecord之間的關係。

2.resumeFocusedStacksTopActivities()

/**
 * Root node for activity containers.
 * TODO: This class is mostly temporary to separate things out of ActivityStackSupervisor.java. The
 * intention is to have this merged with RootWindowContainer.java as part of unifying the hierarchy.
 */
//RootActivityContainer.java:
boolean resumeFocusedStacksTopActivities(
        ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {

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

    boolean result = false;
    if (targetStack != null && (targetStack.isTopStackOnDisplay()
            || getTopDisplayFocusedStack() == targetStack)) {
        result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
    }
    ......
    return result;
}

這裏看targetStack.resumeTopActivityUncheckedLocked()

//ActivityStack.java:
@GuardedBy("mService")
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
    if (mInResumeTopActivity) {
        // Don't even start recursing.
        return false;
    }

    boolean result = false;
    try {
        // Protect against recursion.
        mInResumeTopActivity = true;
        result = resumeTopActivityInnerLocked(prev, options);

        // 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();
        }
    } finally {
        mInResumeTopActivity = false;
    }

    return result;
}

//ActivityStack.java:
@GuardedBy("mService")
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
    // Find the next top-most activity to resume in this stack that is not finishing and is
    // focusable. If it is not focusable, we will fall into the case below to resume the
    // top activity in the next focusable task.
    ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
    ......
    boolean pausing = getDisplay().pauseBackStacks(userLeaving, next, false);
    if (mResumedActivity != null) {
        pausing |= startPausingLocked(userLeaving, false, next, false);
    }
    ......
    if (next.attachedToProcess()) {
        ......
    } else {
        ......
        mStackSupervisor.startSpecificActivityLocked(next, true, true);
    }

    return true;
}

因爲activity所在應用的進程還未生成,此時next.attachedToProcess()明顯是false的。直接看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);
    if (wpc != null && wpc.hasThread()) {
        try {
            realStartActivityLocked(r, wpc, andResume, checkConfig);
            return;
        } catch (RemoteException e) {
        }
    }
    ......
    try {
        if (Trace.isTagEnabled(TRACE_TAG_ACTIVITY_MANAGER)) {
            Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "dispatchingStartProcess:"
                    + r.processName);
        }
        // Post message to start process to avoid possible deadlock of calling into AMS with the
        // ATMS lock held.
        final Message msg = PooledLambda.obtainMessage(
                ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
                r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
        mService.mH.sendMessage(msg);
    } finally {
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }
}

若是已有進程會走realStartActivityLocked()。 這裏走startProcess(),這裏的mService即ActivityTaskManagerService(ATMS),mService.mH是ATMS的內部類 自定義的Handler。
關於這個Handler:它是ATMS initialize()時建立的,它的Looper是AMS中mActivityTaskManager.initialize(mIntentFirewall, mPendingIntentController, DisplayThread.get().getLooper());傳入的,即DisplayThread.get().getLooper()。這個DisplayThread比較特別,能夠看下注釋。
Hanler相關能夠參考下消息機制
接着直接查看ActivityManagerInternal::startProcess。

/**
 * Shared singleton foreground thread for the system.  This is a thread for
 * operations that affect what's on the display, which needs to have a minimum
 * of latency.  This thread should pretty much only be used by the WindowManager,
 * DisplayManager, and InputManager to perform quick operations in real time.
 */
public final class DisplayThread extends ServiceThread {
    private DisplayThread() {
        // DisplayThread runs important stuff, but these are not as important as things running in
        // AnimationThread. Thus, set the priority to one lower.
        super("android.display", Process.THREAD_PRIORITY_DISPLAY + 1, false /*allowIo*/);
    }

ActivityManagerInternal::startProcess,ActivityManagerInternal是抽象類,實現是AMS中的內部類LocalService。

進入AMS,請求建立應用進程

這裏直接看startProcess。

//ActivityManagerService.java:
@Override
public void startProcess(String processName, ApplicationInfo info,
        boolean knownToBeDead, String hostingType, ComponentName hostingName) {
    try {
        synchronized (ActivityManagerService.this) {
            startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
                    new HostingRecord(hostingType, hostingName),
                    false /* allowWhileBooting */, false /* isolated */,
                    true /* keepIfLarge */);
        }
    } finally {
        ......
    }
}

@GuardedBy("this")
final ProcessRecord startProcessLocked(String processName,
        ApplicationInfo info, boolean knownToBeDead, int intentFlags,
        HostingRecord hostingRecord, boolean allowWhileBooting,
        boolean isolated, boolean keepIfLarge) {
    return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
            hostingRecord, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
            null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
            null /* crashHandler */);
}

很清晰,AMS的startProcess()調用了startProcessLocked(),而startProcessLocked()又調用了ProcessList的startProcessLocked()。

//ProcessList.java:
@GuardedBy("mService")
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
        boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,
        boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
        String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
    ProcessRecord app;
    if (!isolated) {
        app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
        ......
    } else {
        ......
    }
    ......
    final boolean success = startProcessLocked(app, hostingRecord, abiOverride);
    return success ? app : null;
}

@GuardedBy("mService")
final boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
        String abiOverride) {
    return startProcessLocked(app, hostingRecord,
            false /* disableHiddenApiChecks */, false /* mountExtStorageFull */, abiOverride);
}

@GuardedBy("mService")
boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
        boolean disableHiddenApiChecks, boolean mountExtStorageFull,
        String abiOverride) {
    ......
    try {
        ......
        if ("1".equals(SystemProperties.get("debug.checkjni"))) {
            runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
        }
        ......
        final String seInfo = app.info.seInfo
                + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
        // Start the process.  It will either succeed and return a result containing
        // the PID of the new process, or else throw a RuntimeException.
        final String entryPoint = "android.app.ActivityThread";
        return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,
                runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
                startTime);
    } catch (RuntimeException e) {
        ......
    }
}

@GuardedBy("mService")
boolean startProcessLocked(HostingRecord hostingRecord,
        String entryPoint,
        ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
        String seInfo, String requiredAbi, String instructionSet, String invokeWith,
        long startTime) {
    app.pendingStart = true;
    app.killedByAm = false;
    app.removed = false;
    app.killed = false;
    ......
    if (mService.mConstants.FLAG_PROCESS_START_ASYNC) {
        mService.mProcStartHandler.post(() -> {
            try {
                final Process.ProcessStartResult startResult = startProcess(app.hostingRecord,
                        entryPoint, app, app.startUid, gids, runtimeFlags, mountExternal,
                        app.seInfo, requiredAbi, instructionSet, invokeWith, app.startTime);
                synchronized (mService) {
                    handleProcessStartedLocked(app, startResult, startSeq);
                }
            } catch (RuntimeException e) {
                ......
            }
        });
        return true;
    } else {
        try {
            final Process.ProcessStartResult startResult = startProcess(hostingRecord,
                    entryPoint, app,
                    uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet,
                    invokeWith, startTime);
            handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
                    startSeq, false);
        } catch (RuntimeException e) {
            ......
        }
        return app.pid > 0;
    }
}

從上面能夠看到,通過了屢次同名方法 startProcessLocked() 調用,在調用過程建立了ProcessRecord對象並處理保存了進程所需的各類信息。
最終調用的是startProcess()。

//ProcessList.java:
private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
        ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
        String seInfo, String requiredAbi, String instructionSet, String invokeWith,
        long startTime) {
    try {
        checkSlow(startTime, "startProcess: asking zygote to start proc");
        final Process.ProcessStartResult startResult;
        if (hostingRecord.usesWebviewZygote()) {
            startResult = startWebView(entryPoint,
                    ......
        } else if (hostingRecord.usesAppZygote()) {
            final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);

            startResult = appZygote.getProcess().start(entryPoint,
                    ......
        } else {
            startResult = Process.start(entryPoint,
                    app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                    app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                    app.info.dataDir, invokeWith, app.info.packageName,
                    new String[] {PROC_START_SEQ_IDENT + app.startSeq});
        }
        checkSlow(startTime, "startProcess: returned from zygote!");
        return startResult;
    } finally {
        ......
    }
}

這裏的hostingRecord是在startProcess()調用時傳入的參數new HostingRecord(hostingType, hostingName),跟蹤能夠看到其mHostingZygote=REGULAR_ZYGOTE。因此走的Process.start()。

Zygote建立應用進程

//Process.java:
public static final ZygoteProcess ZYGOTE_PROCESS = new ZygoteProcess();

public static ProcessStartResult start(@NonNull final String processClass,
                                           @Nullable final String niceName,
                                           int uid, int gid, @Nullable int[] gids,
                                           int runtimeFlags,
                                           int mountExternal,
                                           int targetSdkVersion,
                                           @Nullable String seInfo,
                                           @NonNull String abi,
                                           @Nullable String instructionSet,
                                           @Nullable String appDataDir,
                                           @Nullable String invokeWith,
                                           @Nullable String packageName,
                                           @Nullable String[] zygoteArgs) {
        return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids,
                    runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                    abi, instructionSet, appDataDir, invokeWith, packageName,
                    /*useUsapPool=*/ true, zygoteArgs);
    }

ZYGOTE_PROCESS是新建的ZygoteProcess對象,在不帶參數構造中定義了4中socket的地址。這裏直接看ZygoteProcess.start()。

//ZygoteProcess.java:
public final Process.ProcessStartResult start(@NonNull final String processClass,
                                              ......) {
    ......
    try {
        return startViaZygote(processClass, niceName, uid, gid, gids,
                runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/ false,
                packageName, useUsapPool, zygoteArgs);
    } catch (ZygoteStartFailedEx ex) {
    }
}

private Process.ProcessStartResult startViaZygote(@NonNull final String processClass,
                                                  ......)
                                                  throws ZygoteStartFailedEx {
    ArrayList<String> argsForZygote = new ArrayList<>();

    // --runtime-args, --setuid=, --setgid=,
    // and --setgroups= must go first
    argsForZygote.add("--runtime-args");
    argsForZygote.add("--setuid=" + uid);
    argsForZygote.add("--setgid=" + gid);
    argsForZygote.add("--runtime-flags=" + runtimeFlags);
    if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) {
        argsForZygote.add("--mount-external-default");
    } 
    ......
    synchronized(mLock) {
        // The USAP pool can not be used if the application will not use the systems graphics
        // driver.  If that driver is requested use the Zygote application start path.
        return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
                                          useUsapPool,
                                          argsForZygote);
    }
}

ZygoteProcess.start()調用了startViaZygote,argsForZygote保存了啓動的應用進程的完整參數。最後調用zygoteSendArgsAndGetResult()發送參數 經過socket進行通訊,完成應用進程的fork,並獲取結果Process.ProcessStartResult。
這裏主要看下 openZygoteSocketIfNeeded(),這個是打開Zygote socket的過程。

//ZygoteProcess.java:
@GuardedBy("mLock")
private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
    try {
        attemptConnectionToPrimaryZygote();

        if (primaryZygoteState.matches(abi)) {
            return primaryZygoteState;
        }
        if (mZygoteSecondarySocketAddress != null) {
            // The primary zygote didn't match. Try the secondary.
            attemptConnectionToSecondaryZygote();

            if (secondaryZygoteState.matches(abi)) {
                return secondaryZygoteState;
            }
        }
    } catch (IOException ioe) {
    }
}

@GuardedBy("mLock")
private void attemptConnectionToPrimaryZygote() throws IOException {
    if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
        primaryZygoteState =
                ZygoteState.connect(mZygoteSocketAddress, mUsapPoolSocketAddress);

        maybeSetApiBlacklistExemptions(primaryZygoteState, false);
        maybeSetHiddenApiAccessLogSampleRate(primaryZygoteState);
        maybeSetHiddenApiAccessStatslogSampleRate(primaryZygoteState);
    }
}

private static class ZygoteState implements AutoCloseable {
   static ZygoteState connect(@NonNull LocalSocketAddress zygoteSocketAddress,
            @Nullable LocalSocketAddress usapSocketAddress)
            throws IOException {
        ......
        final LocalSocket zygoteSessionSocket = new LocalSocket();
        .......
        try {
            zygoteSessionSocket.connect(zygoteSocketAddress);
            zygoteInputStream = new DataInputStream(zygoteSessionSocket.getInputStream());
            zygoteOutputWriter =
                    new BufferedWriter(
                            new OutputStreamWriter(zygoteSessionSocket.getOutputStream()),
                            Zygote.SOCKET_BUFFER_SIZE);
        } catch (IOException ex) {
            ......
        }

        return new ZygoteState(zygoteSocketAddress, usapSocketAddress,
                               zygoteSessionSocket, zygoteInputStream, zygoteOutputWriter,
                               getAbiList(zygoteOutputWriter, zygoteInputStream));
    }
}

openZygoteSocketIfNeeded()返回一個 ZygoteState,這個是ZygoteProcess類的內部類,是保存與zygote進程進行通訊時的狀態信息。
attemptConnectionToPrimaryZygote()和attemptConnectionToSecondaryZygote()相似。經過connect()打開socket並經過ZygoteState保存狀態信息。

關於進入connect()後經過socket與zygote進程通訊fork出應用進程的過程 我的也需進一步查看學習 在這裏不說了。

應用進程主線程-執行ActivityThread的main()

當應用進程fork出來後,最終會執行到ActivityThread的main()方法。這個類在 AMS之AMS的啓動 中說的比較多,那時主要是系統進程(system server)。關於應用進程相關的略過,這裏主要是應用進程。

//ActivityThread.java:
public static void main(String[] args) {
    // Install selective syscall interception
    AndroidOs.install();

    // CloseGuard defaults to true and can be quite spammy.  We
    // disable it here, but selectively enable it later (via
    // StrictMode) on debug builds, but using DropBox, not logs.
    CloseGuard.setEnabled(false);

    Environment.initForCurrentUser();

    // Make sure TrustedCertificateStore looks in the right place for CA certificates
    final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
    TrustedCertificateStore.setDefaultUserDirectory(configDir);

    Process.setArgV0("<pre-initialized>");

    Looper.prepareMainLooper();

    ......
    ActivityThread thread = new ActivityThread();
    thread.attach(false, startSeq);

    if (sMainThreadHandler == null) {
        sMainThreadHandler = thread.getHandler();
    }
    ......
    Looper.loop();

    throw new RuntimeException("Main thread loop unexpectedly exited");
}

這裏不少熟悉的地方:
主線程默認建立的Looper,且不可退出。在 Android消息機制(Handler)詳述 詳細說過。
建立了ActivityThread對象,執行了attach(),attach()中這裏第一個參數是false,即非系統進程。 AMS之AMS的啓動 則是true,是系統進程。
下面直接看下ActivityThread.attach()。
注:此時activity還未建立,activity的attach()還在後面。

@UnsupportedAppUsage
//ActivityThread.java:
private void attach(boolean system, long startSeq) {
    sCurrentActivityThread = this;
    mSystemThread = system;
    if (!system) {
        android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
                                                UserHandle.myUserId());
        RuntimeInit.setApplicationObject(mAppThread.asBinder());
        final IActivityManager mgr = ActivityManager.getService();
        try {
            mgr.attachApplication(mAppThread, startSeq);
        } 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 {
                        ActivityTaskManager.getService().releaseSomeActivities(mAppThread);
                    } catch (RemoteException e) {
                        throw e.rethrowFromSystemServer();
                    }
                }
            }
        });
    } else {
        ......
    }
    ......
}

主要來看下mgr.attachApplication()。很明顯這個也是binder機制進行跨進程的,調用的是AMS的attachApplication()。

進入系統進程,將應用進程綁定到ATMS中

//ActivityManagerService.java:
@Override
public final void attachApplication(IApplicationThread thread, long startSeq) {
    if (thread == null) {
        throw new SecurityException("Invalid application interface");
    }
    synchronized (this) {
        int callingPid = Binder.getCallingPid();
        final int callingUid = Binder.getCallingUid();
        final long origId = Binder.clearCallingIdentity();
        attachApplicationLocked(thread, callingPid, callingUid, startSeq);
        Binder.restoreCallingIdentity(origId);
    }
}

@GuardedBy("this")
private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
        int pid, int callingUid, long startSeq) {

    // Find the application record that is being attached...  either via
    // the pid if we are running in multiple processes, or just pull the
    // next app record if we are emulating process with anonymous threads.
    ProcessRecord app;
    long startTime = SystemClock.uptimeMillis();
    long bindApplicationTimeMillis;
    if (pid != MY_PID && pid >= 0) {
        synchronized (mPidsSelfLocked) {
            app = mPidsSelfLocked.get(pid);
        }
    ......
    final String processName = app.processName;
    ......
    final BackupRecord backupTarget = mBackupTargets.get(app.userId);
    try {
        ......
        mAtmInternal.preBindApplication(app.getWindowProcessController());
        final ActiveInstrumentation instr2 = app.getActiveInstrumentation();
        if (app.isolatedEntryPoint != null) {
            // This is an isolated process which should just call an entry point instead of
            // being bound to an application.
            thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs);
        } else if (instr2 != null) {
            thread.bindApplication(processName, appInfo, providers,
                    instr2.mClass,
                    profilerInfo, instr2.mArguments,
                    instr2.mWatcher,
                    instr2.mUiAutomationConnection, testMode,
                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
                    isRestrictedBackupMode || !normalMode, app.isPersistent(),
                    new Configuration(app.getWindowProcessController().getConfiguration()),
                    app.compat, getCommonServicesLocked(app.isolated),
                    mCoreSettingsObserver.getCoreSettingsLocked(),
                    buildSerial, autofillOptions, contentCaptureOptions);
        } else {
            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);
        }
        .......
    } catch (Exception e) {
        ......
    // See if the top visible activity is waiting to run in this process...
    if (normalMode) {
        try {
            didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
        } catch (Exception e) {
            Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
            badApp = true;
        }
    }
    ......
    return true;
}

attachApplication()->attachApplicationLocked(),主要看下thread.bindApplication()和mAtmInternal.attachApplication()。
thread.bindApplication()實際調用的是 ApplicationThread下的 bindApplication()。ApplicationThread是ActivityThread的內部類,private class ApplicationThread extends IApplicationThread.Stub。注意當前是在AMS進程,其中的thread是傳入的 是應用進程主線程。
mAtmInternal.attachApplication()最終調用的是ATMS中的 attachApplication()。

先來看下thread.bindApplication()

//ActivityThread.java->ApplicationThread class:
public final void bindApplication(String processName, ApplicationInfo appInfo,
        ......) {
    ......
    data.contentCaptureOptions = contentCaptureOptions;
    sendMessage(H.BIND_APPLICATION, data);
}

//ActivityThread.java->H class:
class H extends Handler {
    public static final int BIND_APPLICATION        = 110;
    public void handleMessage(Message msg) {
        switch (msg.what) {
            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;
        }
    }
}
//ActivityThread.java:
private void handleBindApplication(AppBindData data) {
    ......
    data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
    ......
    // Continue loading instrumentation.
    if (ii != null) {
        ......
        try {
            final ClassLoader cl = instrContext.getClassLoader();
            mInstrumentation = (Instrumentation)
                cl.loadClass(data.instrumentationName.getClassName()).newInstance();
        ......
    }
    ......
    // 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.
    Application app;

    try {
        app = data.info.makeApplication(data.restrictedBackupMode, null);
        ......
        try {
            mInstrumentation.callApplicationOnCreate(app);
        } catch (Exception e) {
            ......
        }
    }
    ......
}

public final LoadedApk getPackageInfoNoCheck(ApplicationInfo ai,
        CompatibilityInfo compatInfo) {
    return getPackageInfo(ai, compatInfo, null, false, true, false);
}

//Application.java:
/**
* Called when the application is starting, before any activity, service,
* or receiver objects (excluding content providers) have been created.
*/
@CallSuper
public void onCreate() {
}

這時ApplicationThread和ActivityThread在同一進程中,因此bindApplication()經過handler通訊,發送message(BIND_APPLICATION),直接看處處理部分handleBindApplication()。
經過 cl.loadClass(data.instrumentationName.getClassName()).newInstance() 反射建立了Instrumentation對象,這個在 AMS之AMS的啓動 也說過。
經過 getPackageInfoNoCheck() 建立LoadedApk對象並保存在data.info。代碼流程:getPackageInfoNoCheck()->getPackageInfo()->new LoadedApk(),都在ActivityThread中。
經過data.info.makeApplication(data.restrictedBackupMode, null)建立了Application。關鍵代碼看下面。
最後經過mInstrumentation.callApplicationOnCreate(app)調用了app.onCreate();,Application建立完成。
這些操做是thread下的,前面說過是傳入的 應用進程主線程。因此建立Application是在應用進程中的。

//LoadedApk.java:   
@UnsupportedAppUsage
public Application makeApplication(boolean forceDefaultAppClass,
        Instrumentation instrumentation) {
    Application app = null;
    String appClass = mApplicationInfo.className;
    try {            
        java.lang.ClassLoader cl = getClassLoader();
        ......
        ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
        app = mActivityThread.mInstrumentation.newApplication(
                cl, appClass, appContext);
        appContext.setOuterContext(app);
    } catch (Exception e) {
        
    }
    mActivityThread.mAllApplications.add(app);
    mApplication = app;  
    return app;
}

//Instrumentation.java:
public Application newApplication(ClassLoader cl, String className, Context context)
        throws InstantiationException, IllegalAccessException, 
        ClassNotFoundException {
    Application app = getFactory(context.getPackageName())
            .instantiateApplication(cl, className);
    app.attach(context);
    return app;
}

private AppComponentFactory getFactory(String pkg) {
    ......
    return apk.getAppFactory();
}

//AppComponentFactory.java:
public @NonNull Application instantiateApplication(@NonNull ClassLoader cl,
        @NonNull String className)
        throws InstantiationException, IllegalAccessException, ClassNotFoundException {
    return (Application) cl.loadClass(className).newInstance();
}

//Application.java:
/* package */ final void attach(Context context) {
    attachBaseContext(context);
    mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
}
//

這就是makeApplication()方法建立Application的過程。注意 makeApplication()傳入的instrumentation爲null,Application的實例化也是經過反射。

接着看第二點mAtmInternal.attachApplication()

//ActivityTaskManagerService.java:
@HotPath(caller = HotPath.PROCESS_CHANGE)
@Override
public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
    synchronized (mGlobalLockWithoutBoost) {
        return mRootActivityContainer.attachApplication(wpc);
    }
}
//RootActivityContainer.java:
boolean attachApplication(WindowProcessController app) throws RemoteException {
    final String processName = app.mName;
    boolean didSomething = false;
    for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
        final ActivityDisplay display = mActivityDisplays.get(displayNdx);
        final ActivityStack stack = display.getFocusedStack();
        if (stack != null) {
            stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);
            final ActivityRecord top = stack.topRunningActivityLocked();
            final int size = mTmpActivityList.size();
            for (int i = 0; i < size; i++) {
                final ActivityRecord activity = mTmpActivityList.get(i);
                if (activity.app == null && app.mUid == activity.info.applicationInfo.uid
                        && processName.equals(activity.processName)) {
                    try {
                        if (mStackSupervisor.realStartActivityLocked(activity, app,
                                top == activity /* andResume */, true /* checkConfig */)) {
                            didSomething = true;
                        }
                    } catch (RemoteException e) {
                        ......
                    }
                }
            }
        }
    }
    ......
    return didSomething;
}

//ActivityStackSupervisor.java:
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
        boolean andResume, boolean checkConfig) throws RemoteException {
    ......
    try {
        r.startFreezingScreenLocked(proc, 0);
        // schedule launch ticks to collect information about slow apps.
        r.startLaunchTickingLocked();
        r.setProcess(proc);
        ......
        try {
            // Create activity launch transaction.
            final ClientTransaction clientTransaction = ClientTransaction.obtain(
                    proc.getThread(), r.appToken);

            final DisplayContent dc = r.getDisplay().mDisplayContent;
            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));

            // Set desired final state.
            final ActivityLifecycleItem lifecycleItem;
            if (andResume) {
                lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
            } else {
                lifecycleItem = PauseActivityItem.obtain();
            }
            clientTransaction.setLifecycleStateRequest(lifecycleItem);

            // Schedule transaction.
            mService.getLifecycleManager().scheduleTransaction(clientTransaction);
            ......

        } catch (RemoteException e) {
            
        }
    } finally {
    }
    ......
    return true;
}

attachApplication()關鍵代碼 一直調用到realStartActivityLocked()。這裏有幾點注意。

  • 這裏完善了ActivityRecord,設置了進程等信息。整體上能夠理解,應爲ActivityRecord、ProcessRecord等由AMS/ATMS管理,這裏將application綁定到了ATMS。
  • 建立了ClientTransaction對象
  • 設置了ClientTransaction的callback,爲一個建立的LaunchActivityItem對象
  • 設置生命週期,爲建立的lifecycleItem對象
  • 經過mService.getLifecycleManager().scheduleTransaction(clientTransaction)發送請求。這裏的mService爲ATMS,這裏的mService.getLifecycleManager()即ClientLifecycleManager。
  • 建立Application後,經過attachApplication()綁定到ATMS。當前仍是在系統進程中。

建立了ClientTransaction對象和設置callback的相關代碼,能夠了解下。

//ClientTransaction.java
public void addCallback(ClientTransactionItem activityCallback) {
    if (mActivityCallbacks == null) {
        mActivityCallbacks = new ArrayList<>();
    }
    mActivityCallbacks.add(activityCallback);
}

public static ClientTransaction obtain(IApplicationThread client, IBinder activityToken) {
    ClientTransaction instance = ObjectPool.obtain(ClientTransaction.class);
    if (instance == null) {
        instance = new ClientTransaction();
    }
    instance.mClient = client;
    instance.mActivityToken = activityToken;

    return instance;
}
//WindowProcessController.java:
IApplicationThread getThread() {
    return mThread;
}

clientTransaction相關有大體瞭解後,直接看最後發送請求代碼。

//ClientLifecycleManager.java:
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.java
public void schedule() throws RemoteException {
    mClient.scheduleTransaction(this);
}

mClient是啥呢?在建立ClientTransaction對象時賦值的。mClient在obtain()時傳入的,即proc.getThread(),final ClientTransaction clientTransaction = ClientTransaction.obtain(proc.getThread(), r.appToken)
ApplicationThread是ActivityThread的內部類,繼承IApplicationThread.Stub,便是一個Binder。private class ApplicationThread extends IApplicationThread.Stub
ApplicationThread是做爲Activitythread和AMS/ATMS通訊的橋樑。它與ActivityThread之間經過handler通訊,AMS獲取ApplicationThread的binder進行通訊。
這裏開始,實際就是從系統進程回到了應用進程。
這裏的過程是應用進程經過binder(IPC)執行mgr.attachApplication()進入系統進程,ATMS經過回調ApplicationThread.scheduleTransaction(),而後經過handler回到應用進程的主線程。

ATMS回調ApplicationThread的方法,該方法在Binder線程池中的線程執行,因此須要使用Handler來切換線程到ActivityThread所在線程。

因此這裏實際調用的就是ApplicationThread的 scheduleTransaction 方法。下面來看下。

//ActivityThread.java->ApplicationThread class:
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
    ActivityThread.this.scheduleTransaction(transaction);
}

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

//ActivityThread.java:
//public final class ActivityThread extends ClientTransactionHandler
private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);
//TransactionExecutor.java:
/** Initialize an instance with transaction handler, that will execute all requested actions. */
public TransactionExecutor(ClientTransactionHandler clientTransactionHandler) {
    mTransactionHandler = clientTransactionHandler;
}


//ActivityThread.java->H class:
class H extends Handler {
    public void handleMessage(Message msg) {
        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;
        }
    }
}

能夠看到scheduleTransaction() 最終經過hanlder進行處理的,執行到TransactionExecutor的execute()。
注意上面關於TransactionExecutor的建立,this是ActivityThread 做爲參數闖入到構造函數中,ActivityThread是繼承了ClientTransactionHandler的。mTransactionHandler即ActivityThread,這是應用進程的主線程,後面出現要知道。

//TransactionExecutor.java:
public void execute(ClientTransaction transaction) {
    ......
    executeCallbacks(transaction);

    executeLifecycleState(transaction);
    mPendingActions.clear();
}

/** 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();
    ......
    final int size = callbacks.size();
    for (int i = 0; i < size; ++i) {
        final ClientTransactionItem item = callbacks.get(i);
        ......
        item.execute(mTransactionHandler, token, mPendingActions);
        item.postExecute(mTransactionHandler, token, mPendingActions);
        ......
    }
}

在上面realStartActivityLocked()中,設置的callback是LaunchActivityItem對象。這裏execute()最終執行到LaunchActivityItem的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);
    client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
    Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}

上面有說過的,這裏的client就是ActivityThread。因此走到了ActivityThread的handleLaunchActivity()。

回到應用進程,建立activity並執行attach()和onCreate()

這裏的client就是ActivityThread,上面也說過,實際上是應用進程的主線程。
這裏主要是建立出應用第一個Activity,並執行了attach()和onCreate()。

//ActivityThread.java:
public Activity handleLaunchActivity(ActivityClientRecord r,
        PendingTransactionActions pendingActions, Intent customIntent) {
    ......
    final Activity a = performLaunchActivity(r, customIntent);
    ......
    return a;
}
    
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    ActivityInfo aInfo = r.activityInfo;
    ......
    ComponentName component = r.intent.getComponent();
    ......
    ContextImpl appContext = createBaseContextForActivity(r);
    Activity activity = null;
    try {
        java.lang.ClassLoader cl = appContext.getClassLoader();
        activity = mInstrumentation.newActivity(
                cl, component.getClassName(), r.intent);
        ......
    }
    ......
    try {
        Application app = r.packageInfo.makeApplication(false, mInstrumentation);
        ......
        if (activity != 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,
                    r.assistToken);
            ......
            if (r.isPersistable()) {
                mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
            } else {
                mInstrumentation.callActivityOnCreate(activity, r.state);
            }
            ......
            r.activity = activity;
        }
        r.setState(ON_CREATE);
    }
    .......
    return activity;
}

這裏是app啓動中activity建立起來的最後一個階段了。上面主要看3點

  • mInstrumentation.newActivity()建立了一個activity
  • activity.attach(),這個就是Activity中attach()的地方,將Context、ActivityThread、Instrumentation、Application、Window等等重要信息關聯到了activity中。這裏代碼不列出了。
  • mInstrumentation.callActivityOnCreate()。執行了Activity的onCreate()方法。
    下面來看下activity的建立和如何執行到onCreate()的。

建立activity

//Instrumentation.java:
public Activity newActivity(ClassLoader cl, String className,
        Intent intent)
        throws InstantiationException, IllegalAccessException,
        ClassNotFoundException {
    String pkg = intent != null && intent.getComponent() != null
            ? intent.getComponent().getPackageName() : null;
    return getFactory(pkg).instantiateActivity(cl, className, intent);
}

private AppComponentFactory getFactory(String pkg) {
    ......
}

//AppComponentFactory.java:
public @NonNull Activity instantiateActivity(@NonNull ClassLoader cl, @NonNull String className,
        @Nullable Intent intent)
        throws InstantiationException, IllegalAccessException, ClassNotFoundException {
    return (Activity) cl.loadClass(className).newInstance();
}

getFactory()獲取的是AppComponentFactory對象。經過反射生成了Activity。

執行Activity.onCreate()

// Instrumentation.java
public void callActivityOnCreate(Activity activity, Bundle icicle) {
    prePerformCreate(activity);
    activity.performCreate(icicle);
    postPerformCreate(activity);
}

// Activity.java
final void performCreate(Bundle icicle) {
    performCreate(icicle, null);
}

@UnsupportedAppUsage
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
    ......
    if (persistentState != null) {
        onCreate(icicle, persistentState);
    } else {
        onCreate(icicle);
    }
    ......
}

到此,一個應用的啓動過程算是完成了。

附上調用棧

從拋出異常中 獲取方法調用的堆棧信息。在須要的方法中添加以下一行便可:

//android.util.Log
Log.d(TAG, Log.getStackTraceString(new Throwable()));

系統中已經添加了一些相似下面的Trace標記,使用Systrace獲取後進一步查看分析。

Trace.traceBegin(long traceTag, String methodName);
Trace.traceEnd(long traceTag);

下面是幾個方法的調用堆棧信息,供參考瞭解下這個方法,能夠本身嘗試下 會發現很好用^v^。
注意下部分方法有兩次不一樣的內容,這是差別。文章第二部分的流程都是按首次啓動進行的,即與下面兩次中的第一次調用堆棧內容一致。
添加在:Instrumentation.java->execStartActivity()

09-16 10:10:16.899  2520  2520 D flx_ams : java.lang.Throwable
09-16 10:10:16.899  2520  2520 D flx_ams : 	at android.app.Instrumentation.execStartActivity(Instrumentation.java:1681)
09-16 10:10:16.899  2520  2520 D flx_ams : 	at android.app.Activity.startActivityForResult(Activity.java:5255)
09-16 10:10:16.899  2520  2520 D flx_ams : 	at com.android.launcher3.Launcher.startActivityForResult(Launcher.java:1609)
09-16 10:10:16.899  2520  2520 D flx_ams : 	at android.app.Activity.startActivity(Activity.java:5580)
09-16 10:10:16.899  2520  2520 D flx_ams : 	at com.android.launcher3.BaseDraggingActivity.startActivitySafely(BaseDraggingActivity.java:176)
09-16 10:10:16.899  2520  2520 D flx_ams : 	at com.android.launcher3.Launcher.startActivitySafely(Launcher.java:1933)
09-16 10:10:16.899  2520  2520 D flx_ams : 	at com.android.launcher3.touch.ItemClickHandler.startAppShortcutOrInfoActivity(ItemClickHandler.java:267)
09-16 10:10:16.899  2520  2520 D flx_ams : 	at com.android.launcher3.touch.ItemClickHandler.onClickAppShortcut(ItemClickHandler.java:232)
09-16 10:10:16.899  2520  2520 D flx_ams : 	at com.android.launcher3.touch.ItemClickHandler.onClick(ItemClickHandler.java:96)
09-16 10:10:16.899  2520  2520 D flx_ams : 	at com.android.launcher3.touch.ItemClickHandler.lambda$getInstance$0(ItemClickHandler.java:67)
09-16 10:10:16.899  2520  2520 D flx_ams : 	at com.android.launcher3.touch.-$$Lambda$ItemClickHandler$_rHy-J5yxnvGlFKWSh6CdrSf-lA.onClick(Unknown Source:2)
09-16 10:10:16.899  2520  2520 D flx_ams : 	at android.view.View.performClick(View.java:7171)
09-16 10:10:16.899  2520  2520 D flx_ams : 	at android.view.View.performClickInternal(View.java:7148)
09-16 10:10:16.899  2520  2520 D flx_ams : 	at android.view.View.access$3500(View.java:802)
09-16 10:10:16.899  2520  2520 D flx_ams : 	at android.view.View$PerformClick.run(View.java:27409)
09-16 10:10:16.899  2520  2520 D flx_ams : 	at android.os.Handler.handleCallback(Handler.java:883)
09-16 10:10:16.899  2520  2520 D flx_ams : 	at android.os.Handler.dispatchMessage(Handler.java:100)
09-16 10:10:16.899  2520  2520 D flx_ams : 	at android.os.Looper.loop(Looper.java:214)
09-16 10:10:16.899  2520  2520 D flx_ams : 	at android.app.ActivityThread.main(ActivityThread.java:7643)
09-16 10:10:16.899  2520  2520 D flx_ams : 	at java.lang.reflect.Method.invoke(Native Method)
09-16 10:10:16.899  2520  2520 D flx_ams : 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:503)
09-16 10:10:16.899  2520  2520 D flx_ams : 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)

execStartActivity():點擊launcher圖標後的,進入ATMS前的。

添加在:ActivityStack.java->startActivityLocked()

09-16 10:10:16.994   877  1956 D flx_ams : java.lang.Throwable
09-16 10:10:16.994   877  1956 D flx_ams : 	at com.android.server.wm.ActivityStack.startActivityLocked(ActivityStack.java:3163)
09-16 10:10:16.994   877  1956 D flx_ams : 	at com.android.server.wm.ActivityStarter.startActivityUnchecked(ActivityStarter.java:1755)
09-16 10:10:16.994   877  1956 D flx_ams : 	at com.android.server.wm.ActivityStarter.startActivity(ActivityStarter.java:1417)
09-16 10:10:16.994   877  1956 D flx_ams : 	at com.android.server.wm.ActivityStarter.startActivity(ActivityStarter.java:956)
09-16 10:10:16.994   877  1956 D flx_ams : 	at com.android.server.wm.ActivityStarter.startActivity(ActivityStarter.java:586)
09-16 10:10:16.994   877  1956 D flx_ams : 	at com.android.server.wm.ActivityStarter.startActivityMayWait(ActivityStarter.java:1311)
09-16 10:10:16.994   877  1956 D flx_ams : 	at com.android.server.wm.ActivityStarter.execute(ActivityStarter.java:517)
09-16 10:10:16.994   877  1956 D flx_ams : 	at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1075)
09-16 10:10:16.994   877  1956 D flx_ams : 	at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1049)
09-16 10:10:16.994   877  1956 D flx_ams : 	at com.android.server.wm.ActivityTaskManagerService.startActivity(ActivityTaskManagerService.java:1026)
09-16 10:10:16.994   877  1956 D flx_ams : 	at android.app.IActivityTaskManager$Stub.onTransact(IActivityTaskManager.java:1486)
09-16 10:10:16.994   877  1956 D flx_ams : 	at android.os.Binder.execTransactInternal(Binder.java:1045)
09-16 10:10:16.994   877  1956 D flx_ams : 	at android.os.Binder.execTransact(Binder.java:1018)

添加在:RootActivityContainer.java->resumeFocusedStacksTopActivities()

09-16 10:10:17.020   877  1956 D flx_ams : java.lang.Throwable
09-16 10:10:17.020   877  1956 D flx_ams : 	at com.android.server.wm.RootActivityContainer.resumeFocusedStacksTopActivities(RootActivityContainer.java:1162)
09-16 10:10:17.020   877  1956 D flx_ams : 	at com.android.server.wm.ActivityStarter.startActivityUnchecked(ActivityStarter.java:1783)
09-16 10:10:17.020   877  1956 D flx_ams : 	at com.android.server.wm.ActivityStarter.startActivity(ActivityStarter.java:1417)
09-16 10:10:17.020   877  1956 D flx_ams : 	at com.android.server.wm.ActivityStarter.startActivity(ActivityStarter.java:956)
09-16 10:10:17.020   877  1956 D flx_ams : 	at com.android.server.wm.ActivityStarter.startActivity(ActivityStarter.java:586)
09-16 10:10:17.020   877  1956 D flx_ams : 	at com.android.server.wm.ActivityStarter.startActivityMayWait(ActivityStarter.java:1311)
09-16 10:10:17.020   877  1956 D flx_ams : 	at com.android.server.wm.ActivityStarter.execute(ActivityStarter.java:517)
09-16 10:10:17.020   877  1956 D flx_ams : 	at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1075)
09-16 10:10:17.020   877  1956 D flx_ams : 	at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1049)
09-16 10:10:17.020   877  1956 D flx_ams : 	at com.android.server.wm.ActivityTaskManagerService.startActivity(ActivityTaskManagerService.java:1026)
09-16 10:10:17.020   877  1956 D flx_ams : 	at android.app.IActivityTaskManager$Stub.onTransact(IActivityTaskManager.java:1486)
09-16 10:10:17.020   877  1956 D flx_ams : 	at android.os.Binder.execTransactInternal(Binder.java:1045)
09-16 10:10:17.020   877  1956 D flx_ams : 	at android.os.Binder.execTransact(Binder.java:1018)

09-16 10:10:17.039   877   894 D flx_ams : java.lang.Throwable
09-16 10:10:17.039   877   894 D flx_ams : 	at com.android.server.wm.RootActivityContainer.resumeFocusedStacksTopActivities(RootActivityContainer.java:1162)
09-16 10:10:17.039   877   894 D flx_ams : 	at com.android.server.wm.ActivityStack.completePauseLocked(ActivityStack.java:1852)
09-16 10:10:17.039   877   894 D flx_ams : 	at com.android.server.wm.ActivityStack.activityPausedLocked(ActivityStack.java:1773)
09-16 10:10:17.039   877   894 D flx_ams : 	at com.android.server.wm.ActivityTaskManagerService.activityPaused(ActivityTaskManagerService.java:1756)
09-16 10:10:17.039   877   894 D flx_ams : 	at android.app.IActivityTaskManager$Stub.onTransact(IActivityTaskManager.java:1981)
09-16 10:10:17.039   877   894 D flx_ams : 	at android.os.Binder.execTransactInternal(Binder.java:1045)
09-16 10:10:17.039   877   894 D flx_ams : 	at android.os.Binder.execTransact(Binder.java:1018)

注意,這就有兩份不一樣的,具體狀況能夠跟蹤看看。以前講到的與第一份一致。

添加在:ActivityThread.java->attach()

09-16 10:10:17.496  6896  6896 D flx_ams : java.lang.Throwable
09-16 10:10:17.496  6896  6896 D flx_ams : 	at android.app.ActivityThread.attach(ActivityThread.java:7317)
09-16 10:10:17.496  6896  6896 D flx_ams : 	at android.app.ActivityThread.main(ActivityThread.java:7627)
09-16 10:10:17.496  6896  6896 D flx_ams : 	at java.lang.reflect.Method.invoke(Native Method)
09-16 10:10:17.496  6896  6896 D flx_ams : 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:503)
09-16 10:10:17.496  6896  6896 D flx_ams : 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)

添加在:LaunchActivityItem.java->execute()

09-16 10:10:17.850  6896  6896 D flx_ams : java.lang.Throwable
09-16 10:10:17.850  6896  6896 D flx_ams : 	at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
09-16 10:10:17.850  6896  6896 D flx_ams : 	at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
09-16 10:10:17.850  6896  6896 D flx_ams : 	at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
09-16 10:10:17.850  6896  6896 D flx_ams : 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2055)
09-16 10:10:17.850  6896  6896 D flx_ams : 	at android.os.Handler.dispatchMessage(Handler.java:107)
09-16 10:10:17.850  6896  6896 D flx_ams : 	at android.os.Looper.loop(Looper.java:214)
09-16 10:10:17.850  6896  6896 D flx_ams : 	at android.app.ActivityThread.main(ActivityThread.java:7643)
09-16 10:10:17.850  6896  6896 D flx_ams : 	at java.lang.reflect.Method.invoke(Native Method)
09-16 10:10:17.850  6896  6896 D flx_ams : 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:503)
09-16 10:10:17.850  6896  6896 D flx_ams : 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)

點擊的camera,execStartActivity()獲取到的過程

09-16 10:10:18.169  6896  6896 D flx_ams : java.lang.Throwable
09-16 10:10:18.169  6896  6896 D flx_ams : 	at android.app.Instrumentation.execStartActivity(Instrumentation.java:1681)
09-16 10:10:18.169  6896  6896 D flx_ams : 	at android.app.Activity.startActivityForResult(Activity.java:5255)
09-16 10:10:18.169  6896  6896 D flx_ams : 	at android.app.Activity.startActivityForResult(Activity.java:5213)
09-16 10:10:18.169  6896  6896 D flx_ams : 	at android.app.Activity.startActivity(Activity.java:5584)
09-16 10:10:18.169  6896  6896 D flx_ams : 	at android.app.Activity.startActivity(Activity.java:5552)
09-16 10:10:18.169  6896  6896 D flx_ams : 	at com.android.camera.CameraActivity.checkPermissions(CameraActivity.java:2522)
09-16 10:10:18.169  6896  6896 D flx_ams : 	at com.android.camera.CameraActivity.checkCameraPermission(CameraActivity.java:1297)
09-16 10:10:18.169  6896  6896 D flx_ams : 	at com.android.camera.CameraActivity.checkPermissionOnCreate(CameraActivity.java:4874)
09-16 10:10:18.169  6896  6896 D flx_ams : 	at com.android.camera.CameraActivity.onCreateTasks(CameraActivity.java:1722)
09-16 10:10:18.169  6896  6896 D flx_ams : 	at com.android.camera.util.QuickActivity.onCreate(QuickActivity.java:115)
09-16 10:10:18.169  6896  6896 D flx_ams : 	at android.app.Activity.performCreate(Activity.java:7873)
09-16 10:10:18.169  6896  6896 D flx_ams : 	at android.app.Activity.performCreate(Activity.java:7861)
09-16 10:10:18.169  6896  6896 D flx_ams : 	at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1306)
09-16 10:10:18.169  6896  6896 D flx_ams : 	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3310)
09-16 10:10:18.169  6896  6896 D flx_ams : 	at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3491)
9-16 10:10:18.169  6896  6896 D flx_ams : 	at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:84)
09-16 10:10:18.169  6896  6896 D flx_ams : 	at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
09-16 10:10:18.169  6896  6896 D flx_ams : 	at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
09-16 10:10:18.169  6896  6896 D flx_ams : 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2055)
09-16 10:10:18.169  6896  6896 D flx_ams : 	at android.os.Handler.dispatchMessage(Handler.java:107)
09-16 10:10:18.169  6896  6896 D flx_ams : 	at android.os.Looper.loop(Looper.java:214)
09-16 10:10:18.169  6896  6896 D flx_ams : 	at android.app.ActivityThread.main(ActivityThread.java:7643)
09-16 10:10:18.169  6896  6896 D flx_ams : 	at java.lang.reflect.Method.invoke(Native Method)
09-16 10:10:18.169  6896  6896 D flx_ams : 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:503)
09-16 10:10:18.169  6896  6896 D flx_ams : 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
相關文章
相關標籤/搜索