源码阅读之Activity启动与App启动流程 - Android 9.0

源码阅读之Activity启动与App启动流程 - Android 9.0

Android小彩虹2021-08-26 11:04:36210A+A-

前言

为了面试与被面试阅读了Activity的启动流程,整理了这篇文章。 之前一直好奇为什么Android面试经常问Activity启动流程,因为在工作中没有相关的实践。阅读完源码以后才发现,Activity启动流程中包含了许多知识,例如Activity的启动模式如何处理、插件化的hook点等等。不过由于源码冗长,本文只分析Activity的启动流程。

阅读建议:

1、分析基于Android 9.0源码,整理了3张流程图。由于图文排版稀疏,建议新建一个API28的工程配合流程图阅读源码,如果发现文章有什么问题,可以联系我。

2、源码冗长,阅读需要耐心。

3、纸上得来终觉浅,绝知此事要躬行。

4、如果流程图不能放大预览,请阅读原文fiftykg.com

Activity在应用内启动流程

话不多说,先上图,流程图1

热启动

简单介绍一下涉及的类:

工具类,包装了ActivityManagerService的调用。一些插件化方案就是通过hook该类实现的,例如didi的VirtualApk

Android核心服务,负责调度各应用进程,管理四大组件。实现了IActivityManager接口,应用进程能通过Binder机制调用系统服务。

Activity启动的工具类,处理启动activity的各种flag。

管理所有应用的Activity的栈,其中mFocusedStack就是当前应用的activity栈。

启动Activity的消息。收到消息后执行execute方法启动activity。

应用的主线程。

接下来开始分析流程: 流程图1,第1-3步,Activity的startActivity会调用startActivityForResult。当应用已经启动时,会先调用startActivityFromChild。但是无论应用是否启动,最后都会调用Instrumentation.execStartActivity。 正如前面所说,ActivityManagerService实现了IActivityManager.aidl接口,提供了应用进程调用系统服务的方法,而Instrumentation包装了ActivityManagerService的调用。

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

    public void startActivityFromChild(@NonNull Activity child, @RequiresPermission Intent intent, int requestCode, @Nullable Bundle options) {
        ...
        Instrumentation.ActivityResult ar =
            mInstrumentation.execStartActivity(
                this, mMainThread.getApplicationThread(), mToken, child,
                intent, requestCode, options);
        ...
    }

流程图1,第4步,Instrumentation调用ActivityManagerService的startActivity

public ActivityResult execStartActivity( Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options) {
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        ...
        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;
    }

流程图1,第5-6步,ActivityManagerService创建ActivityStarter并执行。

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

    }

流程图1,第7步,由于第6步setMayWait将mayWait设置为true,所以执行startActivityMayWait方法。

    ActivityStarter setMayWait(int userId) {
        mRequest.mayWait = true;
        mRequest.userId = userId;

        return this;
    }
    
    int execute() {
        try {
            if (mRequest.mayWait) {
                return startActivityMayWait(...);
            } else {
                return startActivity(...);
            }
        } finally {
            onExecutionComplete();
        }
    }

流程图1,第8-11步,ActivityStarter处理启动activity的intent和flag比较繁琐,最后会调用ActivityStackSupervisor的resumeFocusedStackTopActivityLocked。

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

        final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
        if (r == null || !r.isState(RESUMED)) {
            mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
        } else if (r.isState(RESUMED)) {
            ...
        }
        return false;
    }

流程图1,第12步,resumeTopActivityInnerLocked是一个非常冗长的方法,该方法会判断栈中是否有需要启动的Activity,判断Activity是否在栈顶等等。如果需要启动的Activity没有被创建,就会执行流程图13步ActivityStackSupervisor的startSpecificActivityLocked方法。

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
    final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
        if (next.app != null && next.app.thread != null) {
            ...
        }else{
            // Whoops, need to restart this activity!
            ...
            mStackSupervisor.startSpecificActivityLocked(next, true, true);
        }
   }

流程图1,第13-14步,startSpecificActivityLocked方法中先判断App是否启动,如果启动则执行realStartActivityLocked。如果未启动则调用ActivityManagerService.startProcessLocked方法启动App。 为了分析方便,我们先看App启动的情况。在realStartActivityLocked方法中,ActivityManangerService会调用应用进程的接口,最终执行ClientTransaction的callBack,也就是LaunchActivityItem。这个调用过程将在稍后分析。

    void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
        // Is this activity's application already running?
        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true);
        if (app != null && app.thread != null) {
            try {
                ...
                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);
    }
    
    final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException {
                ...
                // Create activity launch transaction.
                final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
                        r.appToken);
                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));
                ...
                // Schedule transaction.
                mService.getLifecycleManager().scheduleTransaction(clientTransaction);
                ...
    }

流程图1,第15步,LaunchActivityItem的execute方法执行了ClientTransactionHandler的handleLaunchActivity。而这个ClientTransactionHandler就是ActivityThread。至于为什么是ActivityThread,可以看第二部分。

    @Override
    public void execute(ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions) {
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
        ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
                mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
                mPendingResults, mPendingNewIntents, mIsForward,
                mProfilerInfo, client);
        client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }

流程图1,第16-19,ActivityThread执行handleLaunchActivity方法,调用真正Activity启动方法performLaunchActivity。 performLaunchActivity中调用Instrumentation.newActivity方法创建Activity对象! 创建完成后,performLaunchActivity会继续调用Instrumentation.callActivityOnCreate。这里往下走就会调用Activity.OnCreate。

    // ActivityThread.java:
    @Override
    public Activity handleLaunchActivity(ActivityClientRecord r, PendingTransactionActions pendingActions, Intent customIntent) {
        ...
        final Activity a = performLaunchActivity(r, customIntent);
        ...
        return a;
    }
    
    // ActivityThread.java:
    /** Core implementation of activity launch. */
    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ...
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            ...
        } catch (Exception e) {
            ...
        }

        try {
            ...
            if (activity != null) {
                ...
                activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.referrer, r.voiceInteractor, window, r.configCallback);
                ...
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
                ...
            }
            ...
        } catch (SuperNotCalledException e) {
            throw e;
        } catch (Exception e) {
            ...
        }
        return 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);
    }
    
    // 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();
    }

流程图1,第20-21,Instrumentation.callActivityOnCreate中调用Activity的performCreate。performCreate调用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, PersistableBundle persistentState) {
        ...
        if (persistentState != null) {
            onCreate(icicle, persistentState);
        } else {
            onCreate(icicle);
        }
        ...
    }

IApplicationThread & IActivityManager

上面流程中最难理解的大概就是第15步了,clientTransaction中添加的LaunchActivityItem是如何被执行的?要理解这一步就需要先了解一下系统与应用之间的通信。

Android进程间通过Binder机制进行通信。AMS(ActivityManagerService)与应用进程之间的通信,Android设计了IApplicationThread与IActivityManager两个接口。 两个通信接口都是单向的: IApplicationThread是AMS请求应用进程的接口。 IActivityManager是应用进程请求AMS的接口。

public class ActivityManagerService extends IActivityManager.Stub // ActivityThread的内部类 private class ApplicationThread extends IApplicationThread.Stub 

再来看一下,上面流程第15步的分解流程,流程图2

流程图2,第3步,mClient就是IApplicationThread。

    private IApplicationThread mClient;
    public void schedule() throws RemoteException {
        mClient.scheduleTransaction(this);
    }

流程图2,第4步,ApplicationThread中scheduleTransaction方法直接调用外部类ActivityThread的scheduleTransaction,但是ActivityThread.java中没有scheduleTransaction方法,而是在父类ClientTransactionHandler。

    // ApplicationThread
    @Override
    public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
        ActivityThread.this.scheduleTransaction(transaction);
    }
        
    //ClientTransactionHandler.java
    void scheduleTransaction(ClientTransaction transaction) {
        transaction.preExecute(this);
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }

流程图2,第5步,ClientTransactionHandler中发了一个handler消息EXECUTE_TRANSACTION。这个Handler就是ActivityThread的子类H。在H的handleMessage中可以找到EXECUTE_TRANSACTION的处理。

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

最终会在TransactionExecutor中取出LaunchActivityItem,执行execute。也是Activity启动流程图中的第15步。

AMS是何时获取到IApplicationThread? App如何获取IActivityManager? 答案就在ActivityThread.main方法中,main中调用了attach方法。

    // ActivityThread.java
    private void attach(boolean system, long startSeq) {
        ...
        if (!system) {
            RuntimeInit.setApplicationObject(mAppThread.asBinder());
            final IActivityManager mgr = ActivityManager.getService();
            try {
                mgr.attachApplication(mAppThread, startSeq);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
        } else {
            //system 
        }
        ...
    }

App进程在启动时通过ActivityManager获取单例的IActivityManager,利用IActivityManager的attachApplication接口将IApplicationThread注册到AMS。这样就实现了App与AMS的通信。

App的启动流程

刚才提到了ActivityThread的main方法,这是应用进程的入口。在Activity启动流程中,第13步startSpecificActivityLocked,如果App未启动mService.startProcessLocked就会走到ActivityThread.main方法。

接下来看一下App的启动流程,流程图3

冷启动

流程图3,第14-15步,startSpecificActivityLocked中判断app未启动进入AMS的startProcessLocked,startProcessLocked经过多次重载调用走到startProcess,startProcess调用Process.start启动进程。 这里注意下,Process.start的第一个参数,在其中一个startProcessLocked方法中赋值为"android.app.ActivityThread",搜索字符串就可以找到!

    // ActivityStackSupervisor.java
    void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
        // application is not running
        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
    }
    // ActivityManagerService.java
    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 {
            ...
            final ProcessStartResult startResult;
            if (hostingType.equals("webview_service")) {
                // webview process
            } 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);
        }
    }

流程图3,第16步,Process.start中出现了著名的ZygoteProcess! 传说中Android的所有进程起源于Zygote,Process类只是对Zygote的包装而已。

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

流程图3,第17-20步,zygoteProcess.start调用zygoteProcess.startViaZygote。startViaZygote中通过socket与zygote通信,启动app进程,zygoteSendArgsAndGetResult方法返回app进程的pid。

    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);
        ...
        synchronized(mLock) {
            return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
        }
    }

接下来就是需要寻找argsForZygote中的参数在哪里解析,在zygoteSendArgsAndGetResult方法中有这样一段注释:

/** * 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. */

然而找不到SystemZygoteInit这个类! 既然argsForZygote中参数是一些hardcode的字符串,那解析的地方应该也是hardcode。所以搜了一下参数。 果然在ZygoteInit.java和ZygoteConnection.java中发现了这些参数。ZygoteInit是zygote进程启动类,main方法中创建了ZygoteServer。由ZygoteServer监听Socket请求,并执行相应的命令。ZygoteServer与客户端的通信协议定义在ZygoteConnection.Arguments中。

流程图3,第21-22步,经过上面一波分析,我们看到ZygoteServer的runSelectLoop方法中,接收到Socket请求后,执行了ZygoteConnection.processOneCommand。

    Runnable runSelectLoop(String abiList) {
        while (true) {
            ...
            ZygoteConnection connection = peers.get(i);
            final Runnable command = connection.processOneCommand(this);
            ...
        }

流程图3,第23-24步,processOneCommand中通过readArgumentList方法读取参数,创建Arguments对象时,在Arguments.parseArgs方法中解析参数。将解析后的参数传入Zygote.forkAndSpecialize创建子进程。

    Runnable processOneCommand(ZygoteServer zygoteServer) {
        String args[];
        Arguments parsedArgs = null;
        FileDescriptor[] descriptors;
        try {
            args = readArgumentList();
            descriptors = mSocket.getAncillaryFileDescriptors();
        } catch (IOException ex) {
            throw new IllegalStateException("IOException on command socket", ex);
        }
        ...
        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);
        ....
    }

在readArgumentList中看到了一段与zygoteSendArgsAndGetResult方法遥相呼应的注释

/** * See android.os.Process.zygoteSendArgsAndGetPid() * 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. */

然而在Process中也找不到zygoteSendArgsAndGetPid。感觉是历史代码的注释,误导啊!

流程图3,第25步,processOneCommand执行完forkAndSpecialize后,在子进程(pid=0)中,执行handleChildProc进行子进程初始化。

    Runnable processOneCommand(ZygoteServer zygoteServer) {
        ...
        pid = Zygote.forkAndSpecialize(...);

        try {
            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;
            }
        } finally {
            IoUtils.closeQuietly(childPipeFd);
            IoUtils.closeQuietly(serverPipeFd);
        }
    }

流程图3,第26步,handleChildProc中,invokeWith是socket参数"--invoke-with",在ActivityManagerService的startProcessLocked中赋值,只有在debug的情况下才!null。 isZygote是参数"--start-child-zygote",在ZygoteProcess.start方法中为false。 所以handleChildProc会走到ZygoteInit.zygoteInit。 这里比较奇怪,为什么不是走childZygoteInit,希望有想法的朋友告知一下=。=

    private Runnable handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors, FileDescriptor pipeFd, boolean isZygote) {
        ...
        if (parsedArgs.invokeWith != null) {
            WrapperInit.execApplication(parsedArgs.invokeWith,
                    parsedArgs.niceName, parsedArgs.targetSdkVersion,
                    VMRuntime.getCurrentInstructionSet(),
                    pipeFd, parsedArgs.remainingArgs);

            // Should not get here.
            throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned");
        } else {
            if (!isZygote) {
                return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs,
                        null /* classLoader */);
            } else {
                return ZygoteInit.childZygoteInit(parsedArgs.targetSdkVersion,
                        parsedArgs.remainingArgs, null /* classLoader */);
            }
        }
    }

流程图3,第27-28步,zygoteInit中执行RuntimeInit.applicationInit,applicationInit调用findStaticMain,反射ActivityThread.main方法!

    public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
        if (RuntimeInit.DEBUG) {
            Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
        }

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

    protected static Runnable findStaticMain(String className, String[] argv, ClassLoader classLoader) {
        Class<?> cl;

        try {
            cl = Class.forName(className, true, classLoader);
        } catch (ClassNotFoundException ex) {
            throw new RuntimeException(
                    "Missing class when invoking static main " + className,
                    ex);
        }
        Method m;
        try {
            m = cl.getMethod("main", new Class[] { String[].class });
        } catch (NoSuchMethodException ex) {
            throw new RuntimeException(
                    "Missing static main on " + className, ex);
        } catch (SecurityException ex) {
            throw new RuntimeException(
                    "Problem getting static main on " + className, ex);
        }
        ...
        return new MethodAndArgsCaller(m, argv);
    }

流程图3,第29-33步,回到ActivityThread.main方法中,走到attach中,向AMS注册IApplicationThread,经过多次attachApplicationLocked走到Activity的启动流程,ActivityStackSupervisor的realStartActivityLocked,也就是流程图1的第14步。

    // ActivityManagerService.java
    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);
        }
    }

巨人的肩膀

老罗:Android应用程序内部启动Activity过程(startActivity)的源代码分析

Android四大组件之Activity--应用进程与系统进程的通信

ps: 源码阅读过程中,遇得了许多疑惑的地方。一方面是能力有限,需要多参考前辈的文章,另一方面源码也并非完美,代码中也有许多todo存在,也许还能发现一些bug。对于ZygoteProcess.zygoteSendArgsAndGetResult()与ZygoteConnection.readArgumentList中出现的误导注释,给google提了一个issue,就当阅读源码的纪念了。

以上。

如果觉得文章还不错,帮忙点个赞。

点击这里复制本文地址 以上内容由权冠洲的博客整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!

支持Ctrl+Enter提交

联系我们| 本站介绍| 留言建议 | 交换友链 | 域名展示 | 支付宝红包
本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除

权冠洲的博客 © All Rights Reserved.  Copyright quanguanzhou.top All Rights Reserved
苏公网安备 32030302000848号   苏ICP备20033101号-1
本网站由 提供CDN/云存储服务

联系我们