Android 应用启动流程

570 阅读8分钟

1.前言

上一篇Android系统启动,结尾讲到Launcher启动,当点击Laucher上的图标,就是调用了startActivity来启动各个应用的首页。所以从入口开始。

Laucher发送进程请求

以9.0代码为基准

Launcher 点击图标,会触发 startActivitySafely

    // /packages/apps/Launcher3/src/com/android/launcher3/Launcher.java
    public boolean startActivitySafely(View v, Intent intent, ItemInfo item) {
        boolean success = super.startActivitySafely(v, intent, item);
        if (success && v instanceof BubbleTextView) {
            BubbleTextView btv = (BubbleTextView) v;
            btv.setStayPressed(true);
            setOnResumeCallback(btv);
        }
        return success;
    }
    
    //BaseDraggingActivity
    public boolean startActivitySafely(View v, Intent intent, ItemInfo item) {
        ...
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); //建立新栈
        ...
        try {
            boolean isShortcut = Utilities.ATLEAST_MARSHMALLOW
                    && (item instanceof ShortcutInfo)
                    && (item.itemType == Favorites.ITEM_TYPE_SHORTCUT
                    || item.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT)
                    && !((ShortcutInfo) item).isPromise();
            if (isShortcut) {
                startShortcutIntentSafely(intent, optsBundle, item);
            } else if (user == null || user.equals(Process.myUserHandle())) {
                startActivity(intent, optsBundle); // 触发 startActivity
            } else {
                LauncherAppsCompat.getInstance(this).startActivityForProfile(
                        intent.getComponent(), user, intent.getSourceBounds(), optsBundle);
            }
            getUserEventDispatcher().logAppLaunch(v, intent);
            return true;
        } catch (ActivityNotFoundException|SecurityException e) {
            Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
            Log.e(TAG, "Unable to launch. tag=" + item + " intent=" + intent, e);
        }
        return false;
    }

Launcher本质上还是个Activity,所以startActivity实现为Activity的。

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

当requestCode 为-1时,说明此Activity不需要获取启动Activity的启动结果

    public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
        if (mParent == null) {
            options = transferSpringboardActivityOptions(options);
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
            if (ar != null) {
                mMainThread.sendActivityResult(
                    mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                    ar.getResultData());
            }
            if (requestCode >= 0) {
                mStartedActivity = true;
            }

            cancelInputsAndStartExitTransition(options);
        } else {
            if (options != null) {
                mParent.startActivityFromChild(this, intent, requestCode, options);
            } else {
                // Note we want to go through this method for compatibility with
                // existing applications that may have overridden it.
                mParent.startActivityFromChild(this, intent, requestCode);
            }
        }
    }

由于是启动新应用的第一个Activity,此Activity还没有mParent,所以优先调用 Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity( this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options);

Instrumentation主要用于监控应用与系统的交互。

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

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

    public abstract class Singleton<T> {
        private T mInstance;
        protected abstract T create();
        public final T get() {  //单例
            synchronized (this) {
                if (mInstance == null) {
                    mInstance = create();
                }
               return mInstance;
            }
         }
    }

AMS发送应用进程请求

首先ActivityManager.getService()获取AMS,这里是通过ServiceManager的AIDL获取的。然后调用AMS的 startActiivity。

    //ActivityManagerService
    @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());
    }
    
    
    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,boolean validateIncomingUser) {
        enforceNotIsolatedCaller("startActivity"); //判断调用者是否被隔离
        
        //检查调用者权限
        userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser,Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
                
        return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
                .setCaller(caller)
                .setCallingPackage(callingPackage)
                .setResolvedType(resolvedType)
                .setResultTo(resultTo)
                .setResultWho(resultWho)
                .setRequestCode(requestCode)
                .setStartFlags(startFlags)
                .setProfilerInfo(profilerInfo)
                .setActivityOptions(bOptions)
                .setMayWait(userId)
                .execute();

    }

AMS的startActivity会获取 UserHandle.getCallingUserId(),AMS是通过此UserId来确定调用者的权限

    //ActivityStarter
    int execute() {
            try {
                if (mRequest.mayWait) { // 这里为true,setMayWait(userId) 赋值的
                    return startActivityMayWait(mRequest.caller, mRequest.callingUid, mRequest.callingPackage, mRequest.intent, mRequest.resolvedType,mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo, mRequest.resultWho, mRequest.requestCode, mRequest.startFlags, mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig, mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId, mRequest.inTask, mRequest.reason, mRequest.allowPendingRemoteAnimationRegistryLookup);
                } else {
                    return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent, mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo, mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo, mRequest.resultWho, mRequest.requestCode, mRequest.callingPid, mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid, mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.componentSpecified, mRequest.outActivity, mRequest.inTask, mRequest.reason, mRequest.allowPendingRemoteAnimationRegistryLookup);
                }
            } finally {
                onExecutionComplete();
            }
        }
        
        
    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) {
        ...
        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);
        ...
        return res;
    }
    
    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) {
        ...
        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);
        ...
        return getExternalResult(mLastStartActivityResult);
    }
    
    private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent, String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid, String callingPackage, int realCallingPid, int realCallingUid, int startFlags, SafeActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity, TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup) {
        ...
        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) {
        ...
        mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity, mOptions);
        ...
    }

ActivityStarter 的调用十分复杂,此类是加载Activity的控制类,主要处理Activity与Task和Stack的相关逻辑,进行栈管理。

    //ActivityStackSupervisor
    boolean resumeFocusedStackTopActivityLocked( ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
        ...
        final ActivityRecord r = mFocusedStack.topRunningActivityLocked(); //获取Activity栈顶信息
        if (r == null || !r.isState(RESUMED)) {
            mFocusedStack.resumeTopActivityUncheckedLocked(null, null); //首次启动,栈顶一定处于停止状态
        } else if (r.isState(RESUMED)) {
            // Kick off any lingering app transitions form the MoveTaskToFront operation.
            mFocusedStack.executeAppTransition(targetOptions);
        }

        return false;
    }

首次启动应用的Activity,栈顶一定处于停止状态,所以会走到mFocusedStack.resumeTopActivityUncheckedLocked

    //ActivityStack
    boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
            if (mStackSupervisor.inResumeTopActivity) {
                return false;
            }
    
            boolean result = false;
            try {
                if (next == null || !next.canTurnScreenOn()) {
                    checkReadyForSleep();
                }
            } finally {
                mStackSupervisor.inResumeTopActivity = false;
            }
    
            return result;
        }
        
    private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
        ...
         mStackSupervisor.startSpecificActivityLocked(next, true, false);
        if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
        return true;
    }

代码很长,没法细致分析,我们紧接着跟入startSpecificActivityLocked

    //ActivityStackSupervisor
    void startSpecificActivityLocked(ActivityRecord r,boolean andResume, boolean checkConfig) {

        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true); // 查询Activity所在的进程是否在运行

        getLaunchTimeTracker().setLaunchTime(r);

        if (app != null && app.thread != null) {
            try {
                if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0 || !"android".equals(r.info.packageName)) {
                    app.addPackage(r.info.packageName, r.info.applicationInfo.longVersionCode,
                            mService.mProcessStats);
                }
                realStartActivityLocked(r, app, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting activity "
                        + r.intent.getComponent().flattenToShortString(), e);
            }

        }

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

这里首先会获取当前启动的activity进程信息ProcessRecord,如果进程存在则调用realStartActivityLocked,如果不存在则调用mService.startProcessLocked,此 mService 就是 AMS

    //ActivityManagerService
    private final boolean startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr, boolean disableHiddenApiChecks, String abiOverride) {
        ...
        final int userId = UserHandle.getUserId(app.uid); // 获取进程uid
        ...
        final String entryPoint = "android.app.ActivityThread";//后续要用到的 ActivityThread包名
        return startProcessLocked(hostingType, hostingNameStr, entryPoint, app, uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith, startTime);
        ...
    }
    
    private boolean startProcessLocked(String hostingType, String hostingNameStr, String entryPoint, ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal, String seInfo, String requiredAbi, String instructionSet, String invokeWith, long startTime) {
        ...
        final ProcessStartResult startResult = startProcess(app.hostingType, entryPoint, app, app.startUid, gids, runtimeFlags, mountExternal, app.seInfo, requiredAbi, instructionSet, invokeWith, app.startTime);
        ...
    }
    
    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) {
        ...
        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});
        ...
    }

通知AMS启动进程,将ActivityThread包名传递下去

Zygote进程接受请求并孵化应用进程

    //Process
    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);
    }
    
    //ZygoteProcess
    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 {
        ...
        argsForZygote.add("--runtime-args");
        argsForZygote.add("--setuid=" + uid);
        argsForZygote.add("--setgid=" + gid);
        argsForZygote.add("--runtime-flags=" + runtimeFlags);
        ...
        return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
    }
    
     private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
        ...
        primaryZygoteState = ZygoteState.connect(mSocket);
        ...
        secondaryZygoteState = ZygoteState.connect(mSecondarySocket);
        ...
    }
    
    //Process
     public static final String ZYGOTE_SOCKET = "zygote";
     public static final String SECONDARY_ZYGOTE_SOCKET = "zygote_secondary";
     
    public static final ZygoteProcess zygoteProcess = new ZygoteProcess(ZYGOTE_SOCKET, SECONDARY_ZYGOTE_SOCKET);

将参数传递给 ZygoteProcess,然后构建出进程启动参数argsForZygote,其中openZygoteSocketIfNeeded 建立了与ZygoteState的连接。这里可以看到会有2种连接,在第一种连接zygote连接不上的时候,会再去连接zygote_secondary

    //ZygoteProcess
    private static Process.ProcessStartResult zygoteSendArgsAndGetResult( ZygoteState zygoteState, ArrayList<String> args) throws ZygoteStartFailedEx {
        ...
        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();                            
        ...
    }
    

将启动进程的参数,写入zygoteState中。我们回到ZygoteInit的 main方法中。

//ZygoteInit
public static void main(String argv[]) {
    ...
    String socketName = "zygote";
    ...
    zygoteServer.registerServerSocketFromEnv(socketName);
    ...
    caller = zygoteServer.runSelectLoop(abiList);

runSelectLoop就是等待AMS传递来信息的地方

    Runnable runSelectLoop(String abiList) {
        ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
        ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
        ...
        while (true) {
            ...
            ZygoteConnection connection = peers.get(i);
            final Runnable command = connection.processOneCommand(this);
            ...
        }
    }

当有AMS的请求数据到来时,会获取ZygoteConnection,调用processOneCommand

    Runnable processOneCommand(ZygoteServer zygoteServer) {
        ...
        args = readArgumentList();
        ...
        parsedArgs = new Arguments(args);
        ...
        pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
                parsedArgs.runtimeFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
                parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.startChildZygote,
                parsedArgs.instructionSet, parsedArgs.appDataDir);
        ...
        if (pid == 0) {
                // in child
                zygoteServer.setForkChild();

                zygoteServer.closeServerSocket();
                IoUtils.closeQuietly(serverPipeFd);
                serverPipeFd = null;

                return handleChildProc(parsedArgs, descriptors, childPipeFd,
                        parsedArgs.startChildZygote);
            } else {
                // In the parent. A pid < 0 indicates a failure and will be handled in
                // handleParentProc.
                IoUtils.closeQuietly(childPipeFd);
                childPipeFd = null;
                handleParentProc(pid, descriptors, serverPipeFd);
                return null;
            }
        ...
    }

首先会通过readArgumentList将之前从AMS传递来的启动进程参数读出,然后将参数进行封装,再通过Zygote.forkAndSpecialize fork 出子进程。如果 pid == 0,说明当前的进程为子进程,那么关闭不需要的ServerSocket,调用handleChildProc

    private Runnable handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors, FileDescriptor pipeFd, boolean isZygote) {
        ...
        if (!isZygote) {
            return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, null /* classLoader */);
        } else {
            return ZygoteInit.childZygoteInit(parsedArgs.targetSdkVersion,
                            parsedArgs.remainingArgs, null /* classLoader */);
        }
    }

如果不是Zygote进程,调用ZygoteInit.zygoteInit

    public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {

        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
        RuntimeInit.redirectLogStreams();

        RuntimeInit.commonInit();
        ZygoteInit.nativeZygoteInit();
        return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
    }
    
    protected static Runnable applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
        ...
        final Arguments args = new Arguments(argv);
        ...
        return findStaticMain(args.startClass, args.startArgs, classLoader);
    }

ZygoteInit.nativeZygoteInit是创建Binder线程池,args.startClass就是之前所说的android.app.ActivityThread,通过findStaticMain去调用 ActivityThread 的 main 方法。

ActivityThread启动Activity

    //ActivityThread
    public static void main(String[] args) {
        ...
        Looper.prepareMainLooper();
        ... 
        ActivityThread thread = new ActivityThread();
        thread.attach(false, startSeq);
        ...
        Looper.loop();
        ...
    }
    
    private void attach(boolean system, long startSeq) {
        ...
        final IActivityManager mgr = ActivityManager.getService();
        ...
        mgr.attachApplication(mAppThread, startSeq);
    }

这里会来到我们熟知的主线程,为主线程创建Loop,然后还是回到了 AMS attachApplication。

    //ActivityManagerService
    @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);
        }
    }
    
    
    private final boolean attachApplicationLocked(IApplicationThread thread, int pid, int callingUid, long startSeq) {
        ...
        // 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) {
                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                badApp = true;
            }
        }
        ...
    }

如果此时顶部有个activity在此进程等着显示,则调用mStackSupervisor.attachApplicationLocked,因为此时仅仅是进程启动,activity还未显示

    //ActivityStackSupervisor
    boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
        ...
        if (realStartActivityLocked(activity, app, top == activity /* andResume */, true /* checkConfig */)) {
            didSomething = true;
        }
        ...
    }

这里可以看到和之前的startSpecificActivityLocked都走到了realStartActivityLocked,如果之前进程存在,就不用启动进程了会从startSpecificActivityLocked 直接调用 realStartActivityLocked

//ActivityStackSupervisor
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, boolean checkConfig) throws RemoteException {
        ...
        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));
        ...
        mService.getLifecycleManager().scheduleTransaction(clientTransaction);
        ...

这里是与8.0非常不同的地方,Android 8.0 使用的是app.thread.scheduleLaunchActivity 9.0对此做了封装,创建了ClientTransaction,将LaunchActivityItem作为Callback传入

    //ClientLifecycleManager
    void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
            final IApplicationThread client = transaction.getClient();
            transaction.schedule();
            if (!(client instanceof Binder)) {
                transaction.recycle();
            }
    }
    
    //ClientTransaction
    public void schedule() throws RemoteException {
        mClient.scheduleTransaction(this);
    }
    
    public static ClientTransaction obtain(IApplicationThread client, IBinder activityToken) {
        ...
        instance.mClient = client;
        instance.mActivityToken = activityToken;
        return instance;
    }
    
    //ActivityThread
    @Override
    public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
        ActivityThread.this.scheduleTransaction(transaction);
    }

一轮下来,可以看出 ClientLifecycleManager 调用 scheduleTransaction,最终是 mClient 调用 scheduleTransaction,而 mClient 其实就是 ActivityThread。

    //ClientTransactionHandler
    void scheduleTransaction(ClientTransaction transaction) {
        transaction.preExecute(this);
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }

ClientTransactionHandler 为 ActivityThread 父类,发送 EXECUTE_TRANSACTION消息。

    //ActivityThread H
          case EXECUTE_TRANSACTION:
                    final ClientTransaction transaction = (ClientTransaction) msg.obj;
                    mTransactionExecutor.execute(transaction);
                    if (isSystem()) {
                        transaction.recycle();
                    }
                    break;

这里面 H 是ActivityThread 内部的Handler,是应用程序进程中主线程的消息管理类。因为 ApplicationThread 是一个 Binder ,它的调用逻辑运行在 Binder 线程池中,所以这里需要用 H 将代码逻辑切换到主线程中,ApplicationThread 是 ActivityThread 的内部类. EXECUTE_TRANSACTION会获取ClientTransaction 调用 mTransactionExecutor.execute(transaction);

    //TransactionExecutor
    public void execute(ClientTransaction transaction) {
        final IBinder token = transaction.getActivityToken();
        executeCallbacks(transaction);
        executeLifecycleState(transaction);
        mPendingActions.clear();
    }
    
    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可以得知,callbacks 里面存放着LaunchActivityItem

    //LaunchActivityItem
    public void execute(ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions) {
        ...
        ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
                mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
                mPendingResults, mPendingNewIntents, mIsForward,
                mProfilerInfo, client);
        client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
    }
    
    //TransactionExecutor
    public TransactionExecutor(ClientTransactionHandler clientTransactionHandler) {
        mTransactionHandler = clientTransactionHandler;
    }
    
    //ActivityThread
    private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);

client 为 ClientTransactionHandler, 而通过代码可以发现其实就是ActivityThread

    //ActivityThread
    public Activity handleLaunchActivity(ActivityClientRecord r, PendingTransactionActions pendingActions, Intent customIntent) {
        ...
        final Activity a = performLaunchActivity(r, customIntent);
        ...
    }
    
    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ActivityInfo aInfo = r.activityInfo;
        if (r.packageInfo == null) {
            //1.创建LoadedApk对象
            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo, Context.CONTEXT_INCLUDE_CODE);
        }
        ...
        //2.获取 ComponentName 
        ComponentName component = r.intent.getComponent();
        //3.创建Context
        ContextImpl appContext = createBaseContextForActivity(r);
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();
            //4.创建activity
            activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent);
            ...
        }
        //5.创建 application
        Application app = r.packageInfo.makeApplication(false, mInstrumentation);
        ...
        //6.关联appliction activity context
        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);
        ...
        //7.调用activity onCreate
        if (r.isPersistable()) {
            mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
        } else {
             mInstrumentation.callActivityOnCreate(activity, r.state);
        }
        ...
    }
    
    //Application 创建
    //LoadApk
    public Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation) {
        ...
        ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
        app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);
        ...
        instrumentation.callApplicationOnCreate(app);
        ...
    }
    
    //Instrumentation
    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;
    }
    
    //Application
    final void attach(Context context) {
        attachBaseContext(context);
        mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
    }
    //Activity attach
    //Activity
    final void attach(Context context, ActivityThread aThread,  instr, IBinder token, int ident,  Application application, Intent intent, ActivityInfo info, CharSequence title, Activity parent, String id,  NonConfigurationInstances lastNonConfigurationInstances,  Configuration config, String referrer, IVoiceInteractor voiceInteractor,  Window window, ActivityConfigCallback activityConfigCallback) {
    ...
    mWindow = new PhoneWindow(this, window, activityConfigCallback);
    ...
    mWindow.setWindowManager((WindowManager)context.getSystemService(Context.WINDOW_SERVICE),mToken, mComponent.flattenToString(),(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
        
    }

    //Activity callActivityOnCreate
    //Instrumentation
    public void callActivityOnCreate(Activity activity, Bundle icicle,
            PersistableBundle persistentState) {
        prePerformCreate(activity);
        activity.performCreate(icicle, persistentState);
        postPerformCreate(activity);
    }
    
    //Activity
    final void performCreate(Bundle icicle, PersistableBundle persistentState) {
        mCanEnterPictureInPicture = true;
        restoreHasCurrentPermissionRequest(icicle);
        if (persistentState != null) {
            onCreate(icicle, persistentState);
        } else {
            onCreate(icicle);
        }
        writeEventLog(LOG_AM_ON_CREATE_CALLED, "performCreate");
        mActivityTransitionState.readState(icicle);

        mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(
                com.android.internal.R.styleable.Window_windowNoDisplay, false);
        mFragments.dispatchActivityCreated();
        mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
    }
  1. 创建Apk文件的描述类 LoadedApk
  2. 获取启动 Activity 的 ComponentName ,其中保存了该Activity的包名与类名
  3. 创建 Context 上下文
  4. 创建 activity ,通过classLoader loadClass,然后newInstance出activity
  5. 创建Application,先创建appliction context,然后通过classLoad newInstance 出 application 对象,然后attach context
  6. 关联application context activity ,Activity 创建 PhoneWindow 与 设置 WindowManager
  7. 调用activity的oncreate

至此应用启动流程就结束了

Android 9.0 与 Android 8.0 Activity启动的不同之处

我们回到代码

    //TransactionExecutor
    public void execute(ClientTransaction transaction) {
        final IBinder token = transaction.getActivityToken();
        executeCallbacks(transaction);  // 调用 LaunchActivityItem
        executeLifecycleState(transaction);
        mPendingActions.clear();
    }
    
    private void executeLifecycleState(ClientTransaction transaction) {
        final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest(); // 封装了生命周期
        ...
        cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */);

        lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
        lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
    }
    
    private void cycleToPath(ActivityClientRecord r, int finish, boolean excludeLastState) {
        final int start = r.getLifecycleState();
        final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
        performLifecycleSequence(r, path);
    }
    
    private void performLifecycleSequence(ActivityClientRecord r, IntArray path) {
        final int size = path.size();
        for (int i = 0, state; i < size; i++) {
            state = path.get(i);
            switch (state) {
                case ON_CREATE:
                    mTransactionHandler.handleLaunchActivity(r, mPendingActions,
                            null /* customIntent */);
                    break;
                case ON_START:
                    mTransactionHandler.handleStartActivity(r, mPendingActions);
                    break;
                case ON_RESUME:
                    mTransactionHandler.handleResumeActivity(r.token, false /* finalStateRequest */,
                            r.isForward, "LIFECYCLER_RESUME_ACTIVITY");
                    break;
                case ON_PAUSE:
                    mTransactionHandler.handlePauseActivity(r.token, false /* finished */,
                            false /* userLeaving */, 0 /* configChanges */, mPendingActions,
                            "LIFECYCLER_PAUSE_ACTIVITY");
                    break;
                case ON_STOP:
                    mTransactionHandler.handleStopActivity(r.token, false /* show */,
                            0 /* configChanges */, mPendingActions, false /* finalStateRequest */,
                            "LIFECYCLER_STOP_ACTIVITY");
                    break;
                case ON_DESTROY:
                    mTransactionHandler.handleDestroyActivity(r.token, false /* finishing */,
                            0 /* configChanges */, false /* getNonConfigInstance */,
                            "performLifecycleSequence. cycling to:" + path.get(size - 1));
                    break;
                case ON_RESTART:
                    mTransactionHandler.performRestartActivity(r.token, false /* start */);
                    break;
                default:
                    throw new IllegalArgumentException("Unexpected lifecycle state: " + state);
            }
        }
    }

上诉分析可知,executeCallbacks 会调用到 performCreate 从而开启activity的 onCreate,而 executeLifecycleState会调用cycleToPath

cycleToPath检查Activity的当前状态能否直接切换到transaction请求的状态,如果其中存在某些中间状态,则需要先完成这些中间状态的切换。

最后通过 lifecycleItem.execute 来调用 mTransactionHandler.performXXXActivity,从而达到控制生命周期的地方。

   //Android 8.0 ActivityThread
   private class H extends Handler {
        public static final int LAUNCH_ACTIVITY         = 100;
        public static final int PAUSE_ACTIVITY          = 101;
        public static final int PAUSE_ACTIVITY_FINISHING= 102;
        public static final int STOP_ACTIVITY_SHOW      = 103;
        public static final int STOP_ACTIVITY_HIDE      = 104;
        public static final int SHOW_WINDOW             = 105;
        public static final int HIDE_WINDOW             = 106;
        public static final int RESUME_ACTIVITY         = 107;
        public static final int SEND_RESULT             = 108;
        public static final int DESTROY_ACTIVITY        = 109;
    
       
       public void handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) {
                case LAUNCH_ACTIVITY: {
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
                    final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
                    r.packageInfo = getPackageInfoNoCheck(
                            r.activityInfo.applicationInfo, r.compatInfo);
                    handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                } break;
        }
   }

可以看到 Android 8.0的时候,生命周期的管控还在ActivityThread 消息100-109,到9.0 这些被删除了,替代为 EXECUTE_TRANSACTION 谷歌给ActivityThread 进行的减负,将Activity的生命周期管控完全提出来了,通过状态进行管控,这样的好处是更加的解耦。

总结

  1. Laucher 点击图标 ,发送Activity启动信息给 InstrumentationInstrumentation 再传递给 ActivityMangerService

  2. ActivityManagerService 会调用 ActivityStarterActivityStack的方法,最终将所需参数传递给ActivityStackSupervisor ,此时如果当前进程不存在,则会调用回ActivityManagerServicestartProcessLocked

  3. ActivityManagerService 将带有 android.app.ActivityThread 与进程信息继续传递,首先传递给Process,然后传递给ZygoteProcess,在ZygoteProcess中拼接出进程启动的各类参数,然后建立Socket连接,获取ZygoteState,将进程启动参数写入ZygoteState

  4. 回到ZygoteInit的 main,ZygoteInit在初始化时,便调用了runSelectLoop,以接受由ActivityManagerService传递来的信息,当进程启动参数写入后,ZygoteInit会获取ZygoteConnection,然后通过ZygoteConnection解析出进程启动参数,并且传递给 Zygote.forkAndSpecializenative 层的对应函数,fork出新的子进程,也就是启动Activity所在的进程

  5. ZygoteInit对子进程进行初始化操作,创建Binder线程池,然后反射并且调用ActivityThreadmain方法

  6. ActivityThreadmain ,首先创建Loop,当前线程就是主线程。然后ActivityManagerService连接ActivityThread,将所需参数传递到ActivityStackSupervisor,调用realStartActivityLocked,这里添加LaunchActivityItemClientTransaction的Callback,通过发送EXECUTE_TRANSACTION新的H类的消息,H接受后根据ClientTransaction的Callback取出LaunchActivityItem

  7. LaunchActivityItemexecute,会调用到ActivityThread 的 handleLaunchActivity ,然后调用到performLaunchActivity

  8. ActivityThread 的 performLaunchActivity,(1) 创建LoadApk (2)获取ComponentName (3)创建Context上下文 (4)创建Activity对象 (5) 创建Application (6)activity 关联context application,创建PhoneWindow (7)调用 activity onCreate

image.png

  • startActivity()通过Instrumentation向AMS进程发起startActivity()请求
  • AMS收到启动请求后由ActivityStarter处理Flags和Intent信息,然后再由ActivityStackSupervisor和ActivityStack处理Task和Stack流程
  • 在ActivityStackSupervisor中判断app进程是否存在,若不存在则请求AMS进程创建新进程,app进程存在的情况请直接跳到第7步
  • AMS进程通过Socket方式请求Zygote fork新进程
  • 在新进程里创建ActivityThread(主线程)并开启Looper循环,同时将ApplicationThread绑定到AMS
  • AMS回调ApplicationThread的bindApplication()方法将自身与新进程绑定,并在ActivityThread的handleBindApplication()方法中创建应用的Application
  • Application创建成功后,AMS调用ActivityStackSupervisor# realStartActivityLocked向ActivityThread发送创建Activity请求
  • ActivityThread利用ClassLoader去加载Activity,并回调其生命周期方法。

不同: Android 9.0 ActivityThreadH类,使用EXECUTE_TRANSACTION来替换原来的100-109的 Activity 生命周期消息,将状态都封装到ActivityLifecycleItem的各个子类,具体的实现都在子类当中,减轻了ActivityThread的负担。将状态相关实现进行解耦。