手记

深入理解AMS --- 二 Activity 的启动

深入理解AMS --- 二 Activity 的启动

以桌面启动应用为例分析一下启动一个新的应用的Activiy的过程。

启动Activity

1.1 Activity#startActivity

在launchu 进程中调用 Activity.startActivity  启动一个新的Activity.
最后调用到Instrumentation#execStartActivity

Activity.java:    public void startActivity(Intent intent) {        this.startActivity(intent, null);
    }    
    public void startActivity(Intent intent) {        this.startActivity(intent, null);
    } 
    
    public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {        if (mParent == null) {
            options = transferSpringboardActivityOptions(options);
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
        } else {

        }
    }

1.2 Instrumentation#execStartActivity

在Instrumentation#execStartActivity 中获取AMS的代理,然后调用AMS的startActivity

Instrumentation.java: public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {        try {            int result = ActivityManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {            throw new RuntimeException("Failure from system", e);
        }        return null;
    }

AMS 进程中startActivity

2.1 AMS startActivity 的堆栈

      at android.app.IApplicationThread$Stub$Proxy.scheduleTransaction(IApplicationThread.java:1767)
      at android.app.servertransaction.ClientTransaction.schedule(ClientTransaction.java:129)
      at com.android.server.am.ClientLifecycleManager.scheduleTransaction(ClientLifecycleManager.java:47)
      at com.android.server.am.ClientLifecycleManager.scheduleTransaction(ClientLifecycleManager.java:69)
      at com.android.server.am.ActivityStack.startPausingLocked(ActivityStack.java:1463)
      at com.android.server.am.ActivityStack.resumeTopActivityInnerLocked(ActivityStack.java:2445)
      at com.android.server.am.ActivityStack.resumeTopActivityUncheckedLocked(ActivityStack.java:2292)
      at com.android.server.am.ActivityStackSupervisor.resumeFocusedStackTopActivityLocked(ActivityStackSupervisor.java:2222)
      at com.android.server.am.ActivityStarter.startActivityUnchecked(ActivityStarter.java:1466)
      at com.android.server.am.ActivityStarter.startActivity(ActivityStarter.java:1200)
      at com.android.server.am.ActivityStarter.startActivity(ActivityStarter.java:868)
      at com.android.server.am.ActivityStarter.startActivity(ActivityStarter.java:544)
      at com.android.server.am.ActivityStarter.startActivityMayWait(ActivityStarter.java:1099)
      - locked <0x3741> (a com.android.server.am.ActivityManagerService)
      at com.android.server.am.ActivityStarter.execute(ActivityStarter.java:486)
      at com.android.server.am.ActivityManagerService.startActivityAsUser(ActivityManagerService.java:5117)
      at com.android.server.am.ActivityManagerService.startActivityAsUser(ActivityManagerService.java:5091)
      at com.android.server.am.ActivityManagerService.startActivity(ActivityManagerService.java:5082)
      at android.app.IActivityManager$Stub.onTransact$startActivity$(IActivityManager.java:10084)
      at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:122)
      at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:3288)
      at android.os.Binder.execTransact(Binder.java:731)

2.2  ActivityStarter#startActivity

ActivityStarter#startActivityMayWait 中new 一个ActivityRecord,  ActivityRecord 为Activity 在AMS中的表示,然后在下面的startActivity中赋值。并且找到Activity 所在的ActivityStack.

startActivityUnchecked 中调用ActivityStack#startActivityLocked 找到Activity 所在的TaskRecord, 把Activity 插入TaskRecord 合适的位置。调用
ActivityStackSupervisor#resumeFocusedStackTopActivityLocked

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

    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;            
            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);
    }    
    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;
        }        final ActivityStack stack = mSupervisor.mFocusedStack;        return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,                true /* doResume */, checkedOptions, inTask, outActivity);
    }    

    private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {

        
        mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
                mOptions);        
        if (mDoResume) {            if (!mTargetStack.isFocusable()
                    || (topTaskActivity != null && topTaskActivity.mTaskOverlay
                    && mStartActivity != topTaskActivity)) {

            } else {
                mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
                        mOptions);
            }
        } else if (mStartActivity != null) {
        }        return START_SUCCESS;
    }

2.3 ActivityStackSupervisor#resumeFocusedStackTopActivityLocked

Activity 已经在进入ActivityStack, 然后从Activity 中查找这个Activity 然后调状态设置为resume.

ActivityStackSupervisor.java    boolean resumeFocusedStackTopActivityLocked(
            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {        if (!readyToResume()) {            return false;
        }        if (targetStack != null && isFocusedStack(targetStack)) {            return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        }        return false;
    }

继续回到 ActivityStack  resume Activity.在resumeTopActivityInnerLocked 中先检查桌面的
Activity 状态,桌面Activity 状态需要设置为pause, startPausingLocked 把桌面Activity设置为paused。 由于新的Activity 在另外一个进程中,另外一个进程还没有启动,mStackSupervisor.startSpecificActivityLocked 启动新的Activity 进程。

ActivityStack.javaboolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {        if (mStackSupervisor.inResumeTopActivity) {            // Don't even start recursing.
            return false;
        }        boolean result = false;        try {            // Protect against recursion.
            mStackSupervisor.inResumeTopActivity = true;
            result = resumeTopActivityInnerLocked(prev, options);            // 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 {
            mStackSupervisor.inResumeTopActivity = false;
        }        return result;
    }    
    private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {        boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, false);        if (mResumedActivity != null) {            if (DEBUG_STATES) Slog.d(TAG_STATES,                    "resumeTopActivityLocked: Pausing " + mResumedActivity);
            pausing |= startPausingLocked(userLeaving, false, next, false);
        }        if (next.app != null && next.app.thread != null) {
               
        } else {  
            mStackSupervisor.startSpecificActivityLocked(next, true, true);
        }           
        return true;
    }    
    final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
            ActivityRecord resuming, boolean pauseImmediately) {        if (prev.app != null && prev.app.thread != null) {
                mService.getLifecycleManager().scheduleTransaction(prev.app.thread, prev.appToken,
                        PauseActivityItem.obtain(prev.finishing, userLeaving,
                                prev.configChangeFlags, pauseImmediately));
            } catch (Exception e) {

            }
        } else {

        }
    }

3 桌面Activity pause

      at android.app.IApplicationThread$Stub$Proxy.scheduleTransaction(IApplicationThread.java:1767)
      at android.app.servertransaction.ClientTransaction.schedule(ClientTransaction.java:129)
      at com.android.server.am.ClientLifecycleManager.scheduleTransaction(ClientLifecycleManager.java:47)
      at com.android.server.am.ClientLifecycleManager.scheduleTransaction(ClientLifecycleManager.java:69)
      at com.android.server.am.ActivityStack.startPausingLocked(ActivityStack.java:1463)

3.1 ApplicationThread#scheduleTransaction

通过 ActivityStack.startPausingLocked  函数paused 桌面Activity.通过调用栈可以看出调用了IApplicationThread#scheduleTransaction 通知桌面进程。 ApplicationThread 相关的类也是binder 调用。 ApplicationThread 的Stub 在桌面进程,是ActivityThread 的一个内部类。

private class ApplicationThread extends IApplicationThread.Stub

scheduleTransaction 函数把相关的消息通知到ActivityThread 的

class H extends Handler

3.2 H#handleMessage

然后进入了桌面进程的主线程中进行消息循环,在 H#handleMessage 处理消息。

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;

3.3 TransactionExecutor#execute

在TransactionExecutor 中调用了函数executeCallbacks。executeCallbacks中还原出PauseActivityItem。

TransactionExecutor.java    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");
    }    
    public void executeCallbacks(ClientTransaction transaction) {        final List<ClientTransactionItem> callbacks = transaction.getCallbacks();        
        final IBinder token = transaction.getActivityToken();
        ActivityClientRecord r = mTransactionHandler.getActivityClient(token);        final int size = callbacks.size();        for (int i = 0; i < size; ++i) {            final ClientTransactionItem item = callbacks.get(i);
            log("Resolving callback: " + item);
       

            item.execute(mTransactionHandler, token, mPendingActions);
            item.postExecute(mTransactionHandler, token, mPendingActions);
        }
    }

3.4 PauseActivityItem

  1. PauseActivityItem 的execute 执行ActivityThread 的handlePauseActivity。
    然后调用Activity的 performPaused, 桌面的Activity 进入暂停状态

  2. postExecute 调用AMS activityPaused,通知AMS 桌面Activity pause.

PauseActivityItem.javapublic class PauseActivityItem extends ActivityLifecycleItem {    private static final String TAG = "PauseActivityItem";    private boolean mFinished;    private boolean mUserLeaving;    private int mConfigChanges;    private boolean mDontReport;    @Override
    public void execute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
        client.handlePauseActivity(token, mFinished, mUserLeaving, mConfigChanges, pendingActions,                "PAUSE_ACTIVITY_ITEM");
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }    @Override
    public void postExecute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {        if (mDontReport) {            return;
        }        try {            // TODO(lifecycler): Use interface callback instead of AMS.
            ActivityManager.getService().activityPaused(token);
        } catch (RemoteException ex) {            throw ex.rethrowFromSystemServer();
        }
    }
AMS    @Override
    public final void activityPaused(IBinder token) {        final long origId = Binder.clearCallingIdentity();        synchronized(this) {
            ActivityStack stack = ActivityRecord.getStackLocked(token);            if (stack != null) {
                stack.activityPausedLocked(token, false);
            }
        }
        Binder.restoreCallingIdentity(origId);
    }

AMS(二)  Activity 的启动过程A.png

四  AMS 启动新进程

AMS pause 桌面Activity, 开始启动新Activity 所在的进程

4.1 startProcessLocked

startSpecificActivityLocked 检查Activity所在的进程是否真的启动。Activity 所在的进程还没有启动,启动Activity 所在的进程。

ActivityStackSupervisor.java 

void startSpecificActivityLocked(ActivityRecord r,            boolean andResume, boolean checkConfig) {
        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true);        if (app != null && app.thread != null) {
            
                realStartActivityLocked(r, app, andResume, checkConfig);                return;
            } catch (RemoteException e) {
          
            }

        }

        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,                "activity", r.intent.getComponent(), false, false, true);
    }

startProcessLocked 要检查多App 共享进程的情况。

AMS    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {        final boolean success = startProcessLocked(app, hostingType, 
    }    
    private ProcessStartResult startProcess(String hostingType, String entryPoint,
            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
            String seInfo, String requiredAbi, String instructionSet, String invokeWith,            long startTime) {        try {
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
                    app.processName);
            checkTime(startTime, "startProcess: asking zygote to start proc");            final ProcessStartResult startResult;            if (hostingType.equals("webview_shttp://assets.processon.com/chart_image/5bda76eee4b0878bf41d8334.png?_=1543231861493ervice")) {
                startResult = startWebView(entryPoint,
                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, null,                        new String[] {PROC_START_SEQ_IDENT + app.startSeq});
            } else {
                startResult = Process.start(entryPoint,
                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, invokeWith,                        new String[] {PROC_START_SEQ_IDENT + app.startSeq});
            }
            checkTime(startTime, "startProcess: returned from zygote!");            return startResult;
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        }
    }
    public static final ProcessStartResult start(final String processClass,                                  final String niceName,                                  int uid, int gid, int[] gids,                                  int runtimeFlags, int mountExternal,                                  int targetSdkVersion,
                                  String seInfo,
                                  String abi,
                                  String instructionSet,
                                  String appDataDir,
                                  String invokeWith,
                                  String[] zygoteArgs) {        return zygoteProcess.start(processClass, niceName, uid, gid, gids,
                    runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                    abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
    }
    public final Process.ProcessStartResult start(final String processClass,                                                  final String niceName,                                                  int uid, int gid, int[] gids,                                                  int runtimeFlags, int mountExternal,                                                  int targetSdkVersion,
                                                  String seInfo,
                                                  String abi,
                                                  String instructionSet,
                                                  String appDataDir,
                                                  String invokeWith,
                                                  String[] zygoteArgs) {        try {            return startViaZygote(processClass, niceName, uid, gid, gids,
                    runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                    abi, instructionSet, appDataDir, invokeWith, false /* startChildZygote */,
                    zygoteArgs);
        } catch (ZygoteStartFailedEx ex) {
            Log.e(LOG_TAG,                    "Starting VM process through Zygote failed");            throw new RuntimeException(                    "Starting VM process through Zygote failed", ex);
        }
    }    
    private Process.ProcessStartResult startViaZygote(final String processClass,                                                      final String niceName,                                                      final int uid, final int gid,                                                      final int[] gids,                                                      int runtimeFlags, int mountExternal,                                                      int targetSdkVersion,
                                                      String seInfo,
                                                      String abi,
                                                      String instructionSet,
                                                      String appDataDir,
                                                      String invokeWith,                                                      boolean startChildZygote,
                                                      String[] extraArgs)
                                                      throws ZygoteStartFailedEx {
        ArrayList<String> argsForZygote = new ArrayList<String>();        // --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");
        } else if (mountExternal == Zygote.MOUNT_EXTERNAL_READ) {
            argsForZygote.add("--mount-external-read");
        } else if (mountExternal == Zygote.MOUNT_EXTERNAL_WRITE) {
            argsForZygote.add("--mount-external-write");
        }
        argsForZygote.add("--target-sdk-version=" + targetSdkVersion);        // --setgroups is a comma-separated list
        if (gids != null && gids.length > 0) {
            StringBuilder sb = new StringBuilder();
            sb.append("--setgroups=");            int sz = gids.length;            for (int i = 0; i < sz; i++) {                if (i != 0) {
                    sb.append(',');
                }
                sb.append(gids[i]);
            }

            argsForZygote.add(sb.toString());
        }        if (niceName != null) {
            argsForZygote.add("--nice-name=" + niceName);
        }        if (seInfo != null) {
            argsForZygote.add("--seinfo=" + seInfo);
        }        if (instructionSet != null) {
            argsForZygote.add("--instruction-set=" + instructionSet);
        }        if (appDataDir != null) {
            argsForZygote.add("--app-data-dir=" + appDataDir);
        }        if (invokeWith != null) {
            argsForZygote.add("--invoke-with");
            argsForZygote.add(invokeWith);
        }        if (startChildZygote) {
            argsForZygote.add("--start-child-zygote");
        }

        argsForZygote.add(processClass);        if (extraArgs != null) {            for (String arg : extraArgs) {
                argsForZygote.add(arg);
            }
        }        synchronized(mLock) {            return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
        }
    }// 通过socket 检查新进程的启动情况
 private static Process.ProcessStartResult zygoteSendArgsAndGetResult(
            ZygoteState zygoteState, ArrayList<String> args)
            throws ZygoteStartFailedEx {        try {            /**
             * See com.android.internal.os.SystemZygoteInit.readArgumentList()
             * Presently the wire format to the zygote process is:
             * a) a count of arguments (argc, in essence)
             * b) a number of newline-separated argument strings equal to count
             *
             * After the zygote process reads these it will write the pid of
             * the child or -1 on failure, followed by boolean to
             * indicate whether a wrapper process was used.
             */
            final BufferedWriter writer = zygoteState.writer;            final DataInputStream inputStream = zygoteState.inputStream;

            writer.write(Integer.toString(args.size()));
            writer.newLine();            for (int i = 0; i < sz; i++) {
                String arg = args.get(i);
                writer.write(arg);
                writer.newLine();
            }

            writer.flush();            // Should there be a timeout on this?
            Process.ProcessStartResult result = new Process.ProcessStartResult();            // Always read the entire result from the input stream to avoid leaving
            // bytes in the stream for future process starts to accidentally stumble
            // upon.
            result.pid = inputStream.readInt();
            result.usingWrapper = inputStream.readBoolean();            if (result.pid < 0) {                throw new ZygoteStartFailedEx("fork() failed");
            }            return result;
        } catch (IOException ex) {
            zygoteState.close();            throw new ZygoteStartFailedEx(ex);
        }
    }

五  Zygote 进程fork

Zygote 的fork 过程参考SystemService 的启动流程。Zygote fork 后也是通过反射的方法找到一个main 函数,这时候因为启动的是App 进程。所以这个main 函数为ActivityThread 的main函数。

六 fork 后的新进程的  ActivityThread

fork 以后启动ActivityThread 的main 函数,在Main 函数中完成Looper的初始化,最重要的一个调用就是 attach

6.1 ActivityThread attach

mgr.attachApplication(mAppThread, startSeq);

    public static void main(String[] args) {
        
        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");
    }    
    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();
            }
        } else {

        }
    }

6.2 AMS 的 attachApplication

AMS 的attachApplication 依次调用了ApplicationThread 的

  1. bindApplication   // 创建Application

  2. scheduleTransaction(clientTransaction); // Resume Activity

AMS:    @Override
    public final void attachApplication(IApplicationThread thread, long startSeq) {        synchronized (this) {            int callingPid = Binder.getCallingPid();            final int callingUid = Binder.getCallingUid();            final long origId = Binder.clearCallingIdentity();
            attachApplicationLocked(thread, callingPid, callingUid, startSeq);
            Binder.restoreCallingIdentity(origId);
        }
    }    
    
    @GuardedBy("this")    private final boolean attachApplicationLocked(IApplicationThread thread,            int pid, int callingUid, long startSeq) {        // It's possible that process called attachApplication before we got a chance to
        // update the internal state.

        try {            if (app.isolatedEntryPoint != null) {

            } else if (app.instr != null) {
                thread.bindApplication(processName, appInfo, providers,
                        app.instr.mClass,
                        profilerInfo, app.instr.mArguments,
                        app.instr.mWatcher,
                        app.instr.mUiAutomationConnection, testMode,
                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
                        isRestrictedBackupMode || !normalMode, app.persistent,                        new Configuration(getGlobalConfiguration()), app.compat,
                        getCommonServicesLocked(app.isolated),
                        mCoreSettingsObserver.getCoreSettingsLocked(),
                        buildSerial, isAutofillCompatEnabled);
            } else {
                thread.bindApplication(processName, appInfo, providers, null, profilerInfo,                        null, null, null, testMode,
                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
                        isRestrictedBackupMode || !normalMode, app.persistent,                        new Configuration(getGlobalConfiguration()), app.compat,
                        getCommonServicesLocked(app.isolated),
                        mCoreSettingsObserver.getCoreSettingsLocked(),
                        buildSerial, isAutofillCompatEnabled);
            }
        
        } catch (Exception e) {

        }        // See if the top visible activity is waiting to run in this process...
        if (normalMode) {            try {                if (mStackSupervisor.attachApplicationLocked(app)) {
                    didSomething = true;
                }
            } catch (Exception e) {

            }
        }        
        return true;
    }
    boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {        final String processName = app.processName;        boolean didSomething = false;        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {            final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);            for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {                final ActivityStack stack = display.getChildAt(stackNdx);                if (!isFocusedStack(stack)) {                    continue;
                }
                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.uid == activity.info.applicationInfo.uid
                            && processName.equals(activity.processName)) {                        try {                            if (realStartActivityLocked(activity, app,
                                    top == activity /* andResume */, true /* checkConfig */)) {
                                didSomething = true;
                            }
                        } catch (RemoteException e) {                            throw e;
                        }
                    }
                }
            }
        }        return didSomething;
    }

6.3 realStartActivityLocked

realStartActivityLocked 中创建了一个ClientTransaction。ClientTransaction 先后调用了下main两个函数。

  1. clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),   // LaunchActivityItem

  2. clientTransaction.setLifecycleStateRequest(lifecycleItem);  // ResumeActivityItem


ActivityStackSupervisor.java 

    final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,            boolean andResume, boolean checkConfig) throws RemoteException {        try {            try {                // Create activity launch transaction.
                final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
                        r.appToken);
                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);                // Schedule transaction.
                mService.getLifecycleManager().scheduleTransaction(clientTransaction);
            } catch (RemoteException e) {
            
            }
        } finally {
        }        return true;
    }




作者:赤兔欢
链接:https://www.jianshu.com/p/c1d1718dde1f


0人推荐
随时随地看视频
慕课网APP