天天看點

源碼閱讀之Activity啟動與App啟動流程

本文簡單分析一下activity的啟動流程。

分析基于Android 9.0源碼,有興趣的朋友可以在AndroidStudio建立一個API28的HelloWorld工程跟着看,如果發現文章有什麼問題,可以聯系我。

Activity在應用内啟動流程

話不多說,先上圖,流程圖1:

源碼閱讀之Activity啟動與App啟動流程

簡單介紹一下涉及的類:

  • Instrumentation

工具類,包裝了ActivityManagerService的調用。一些插件化方案就是通過hook該類實作的,例如didi的VirtualApk

  • ActivityManagerService

Android核心服務,負責排程各應用程序,管理四大元件。實作了IActivityManager接口,應用程序能通過Binder機制調用系統服務。

  • ActivityStarter

Activity啟動的工具類,處理啟動activity的各種flag。

  • ActivityStackSupervisor

管理所有應用的Activity的棧,其中mFocusedStack就是目前應用的activity棧。

  • LaunchActivityItem

啟動Activity的消息。收到消息後執行execute方法啟動activity。

  • ActivityThread

應用的主線程。

接下來開始分析流程:

流程圖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:

源碼閱讀之Activity啟動與App啟動流程

流程圖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:

源碼閱讀之Activity啟動與App啟動流程

流程圖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,就當閱讀源碼的紀念了。

以上。