源碼閱讀之Activity啓動與App啓動流程 - Android 9.0

前言

爲了面試與被面試閱讀了Activity的啓動流程,整理了這篇文章。 以前一直好奇爲何Android面試常常問Activity啓動流程,由於在工做中沒有相關的實踐。閱讀完源碼之後才發現,Activity啓動流程中包含了許多知識,例如Activity的啓動模式如何處理、插件化的hook點等等。不過因爲源碼冗長,本文只分析Activity的啓動流程。html

閱讀建議:java

一、分析基於Android 9.0源碼,整理了3張流程圖。因爲圖文排版稀疏,建議新建一個API28的工程配合流程圖閱讀源碼,若是發現文章有什麼問題,能夠聯繫我。android

二、源碼冗長,閱讀須要耐心。git

三、紙上得來終覺淺,絕知此事要躬行。github

四、若是流程圖不能放大預覽,請閱讀原文fiftykg.comweb

Activity在應用內啓動流程

話很少說,先上圖,流程圖1面試

熱啓動

簡單介紹一下涉及的類:

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

Android核心服務,負責調度各應用進程,管理四大組件。實現了IActivityManager接口,應用進程能經過Binder機制調用系統服務。socket

Activity啓動的工具類,處理啓動activity的各類flag。ide

管理全部應用的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,就當閱讀源碼的記念了。

以上。

若是以爲文章還不錯,幫忙點個贊。

相關文章
相關標籤/搜索