Android之9.0Activity啓動流程(一)

注:下列源碼均基於9.0,可通過下列方式下載本文相關源碼到本地:

  • git clone https://aosp.tuna.tsinghua.edu.cn/platform/packages/apps/Launcher3
  • git clone https://aosp.tuna.tsinghua.edu.cn/platform/frameworks/base

參考博客:如何下載和閱讀Android源碼

前言

本篇文章將根據源碼解剖Android的Activity的啓動流程,需注意的是下列的分析均基於Android9.0, 9.0版本相較於之前幾個版本做了許多改動和重構,但是整體的流程是變化不大。根據啓動Activity時機的不同,可分爲根Activity的啓動流程和普通Activity啓動流程,根Activity啓動流程又可以稱爲應用程序啓動流程,即在桌面上點擊一個應用圖標到進入到應用第一個Activity的流程。而普通Activity的啓動流程就是在一個應用裏開啓另外一個Activity的流程。由於兩種啓動流程是有重疊的,而根Activity的啓動流程更加複雜,所以接下來我們重點分析根Activity的啓動流程,而普通Activity的啓動流程在涉及的地方會稍微提一下。由於考慮到篇幅較長,這裏將分爲兩篇來介紹。

這篇將分析啓動流程中的應用進程的創建:

  • Launcher進程請求AMS
  • AMS發送創建應用進程請求
  • Zygote進程接受請求並孵化應用進程
  • 應用進程啓動ActivityThread

一、Launcher進程請求AMS

上面我們提到根Activity的啓動流程其實就是桌面上點擊一個應用圖標進入到應用的第一個Activity的流程,其實桌面也可以看成一個程序,即Launcher。當系統開機後,Launcher也隨之被啓動,然後將已經安裝的應用程序圖標顯示到桌面上,所以當我們點擊一個應用圖標其實就是相當於點擊活動中的一個button,其相應事件就是Launcher進程請求AMS來啓動該應用程序。

1. 時序圖

在這裏插入圖片描述

2. 詳細過程

請求的入口就是Launcher的startActivitySafe方法,如下:

packages/apps/Launcher3/src/com/android/launcher3/Launcher.java

    public boolean startActivitySafely(View v, Intent intent, ItemInfo item) {
        ...
        // 根Activity會在新的任務棧中啓動
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        
        try {
            ...
            if (isShortcut) {
                // Shortcuts need some special checks due to legacy reasons.
                startShortcutIntentSafely(intent, optsBundle, item);
            } else if (user == null || user.equals(Process.myUserHandle())) {
                // 調用startActivity
                startActivity(intent, optsBundle);
            } else {
                LauncherAppsCompat.getInstance(this).startActivityForProfile(
                        intent.getComponent(), user, intent.getSourceBounds(), optsBundle);
            }
            ...
            return true;
        } catch (ActivityNotFoundException|SecurityException e) {
            ...
        }
        return false;
    }

可以發現該方法爲根Activity設置了flag,即根Activity會在新的任務棧中啓動。然後會調用我們熟悉的startActivity方法,而在Launcher並沒有這個方法,所以我們自然想到了應該是父類的方法,然後讓我們來看看Launcher繼承了哪些類?

public class Launcher extends BaseDraggingActivity implements LauncherExterns,
        LauncherModel.Callbacks, LauncherProviderChangeListener, UserEventDelegate{
            
        }
public abstract class BaseDraggingActivity extends BaseActivity
        implements WallpaperColorInfo.OnChangeListener {
        
        }
public abstract class BaseActivity extends Activity implements UserEventDelegate{
}

其實一直追蹤下去,你就會發現其實Launcher調用的startActivity其實就是Activity中的startActivity。從這裏也可以證明Launcher其實也是個Activity。所以在Launcher啓動一個app,和我們平時在startActivity基本是一樣的(基本一樣,不代表完全一樣,通過後文分析你就會明白!),於是我們來看看我們熟悉的Activity中的startActivity的源碼是如何的:

源碼:frameworks/base/core/java/android/app/Activity.java

    @Override
    public void startActivity(Intent intent, @Nullable Bundle options) {
        //第二個參數爲-1表示Launcher不需要知道根Activity的啓動結果
        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);
        }
    }
    public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {
        startActivityForResult(intent, requestCode, null);
    }


    public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
        //mParent表示當前Activity的父類,當根活動還沒創建則mParent==null    
        if (mParent == null) {
            options = transferSpringboardActivityOptions(options);
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
           ... 
        } 
        ...
    }

從上面代碼可以發現startActivity的最終實現是startActivityForResult,startActivity()第二個參數爲-1表示Launcher不需要知道根Activity的啓動結果,然後在startActivityForResult中由於此時根Activity還沒有創建,故mParent=null,所以我們只需要關注mParent=null的情況。在這種情況中會調用Instrumentation的execStartActivity。這時候也許你就會問這個Instrumentation是什麼?爲什麼要交給她弄呢?其實Instrumentation這個類很重要,重要體現在對Activity生命週期的調用根本離不開她。每個Activity都持有Instrumentation對象的一個引用,但是整個進程只會存在一個Instrumentation對象。迴歸正題,讓我們瞧瞧Instrumentation的execStartActivity這個方法。

frameworks/base/core/java/android/app/Instrumentation.java

    public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        ...
        try {
		   ...
		    //獲取AMS的代理對象
            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的getService方法來得到AMS的代理對象,然後調用這個代理對象的

startActivity方法,那麼這個代理對象是誰呢?讓我們一探究竟

    @UnsupportedAppUsage
    public static IActivityManager getService() {
        return IActivityManagerSingleton.get();
    }

    @UnsupportedAppUsage
    private static final Singleton<IActivityManager> IActivityManagerSingleton =
            new Singleton<IActivityManager>() {
                @Override
                protected IActivityManager create() {
                    //得到activity的service引用,即IBinder類型的AMS引用
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
					//轉換成IActivityManager對象
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);
                    return am;
                }
            };

可以發現在Singleton中的create方法中由於b是AMS引用作爲服務端處於SystemServer進程中,與當前Launcher進程作爲客戶端與服務端不在同一個進程,所以am返回的是IActivityManager.Stub的代理對象,此時如果要實現客戶端與服務端進程間的通信,只需要在AMS繼承了IActivityManager.Stub類並實現了相應的方法,而通過下面的代碼可以發現AMS剛好是繼承了IActivityManager.Stub類的,這樣Launcher進程作爲客戶端就擁有了服務端AMS的代理對象,然後就可以調用AMS的方法來實現具體功能了,就這樣Launcher的工作就交給AMS實現了。

public class ActivityManagerService extends IActivityManager.Stub
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
        
        }

二、AMS發送創建應用進程請求

通過上面的分析,我們已經知道現在任務已經交給了AMS,入口是AMS的startActivity。

1. 時序圖

在這裏插入圖片描述

2. 詳細過程

2.1 AMS將請求任務轉移給Process

首先來看看在AMS中的startActivity方法:

源碼:frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

    @Override
    public final int startActivity(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                resultWho, requestCode, startFlags, profilerInfo, bOptions,
                UserHandle.getCallingUserId());
    }

    @Override
    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) {
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
                true /*validateIncomingUser*/);
    }

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

        // TODO: Switch to user app stacks here.
        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();

    }

startActivity方法經過多個方法調用會去執行startActivityAsUser方法,在startActivityAsUser方法最後會返回mActivityStartController的一長串鏈式調用方法,如果AlertDialog的話,應該不難看出這鏈式方法肯定都是返回一個類型的對象的,我們只需要看看obtainStarter的返回類型就可以知道這個對象是什麼類型了。

frameworks/base/services/core/java/com/android/server/am/ActivityStartController.java

    ActivityStarter obtainStarter(Intent intent, String reason) {
        return mFactory.obtain().setIntent(intent).setReason(reason);
    }

可以發現這個obtainStarter返回的是ActivityStarter類型的,所以鏈式方法就是對ActivityStarter對象設置了要啓動的活動的相關信息,最後再調用ActivityStarter對象execute方法。所以我們下一步所需要看的就是這個execute方法。

frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java

    int execute() {
        try {
            // TODO(b/64750076): Look into passing request directly to these methods to allow
            // for transactional diffs and preprocessing.
            if (mRequest.mayWait) {
                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,
                        mRequest.originatingPendingIntent);
            } 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,
                        mRequest.originatingPendingIntent);
            }
        } finally {
            onExecutionComplete();
        }
    }

因爲在startActivityAsUser的鏈式方法中我們調用了setMayWait這個方法,所以這裏的mRequest.mayWait爲true,故會繼續調用startActivityMayWait方法。

ActivityStarter#startActivityMayWait

    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,
            PendingIntentRecord originatingPendingIntent) {
        .....
        //根據intent在系統中找到合適的應用的activity,如果有多個activity可選擇,
		//則會彈出ResolverActivity讓用戶選擇合適的應用。
        ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);


        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, originatingPendingIntent);
        ....

    }

    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 startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
                ActivityRecord[] outActivity) {
        ...
            result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                    startFlags, doResume, options, inTask, outActivity);
        ...

        postStartActivityProcessing(r, result, mTargetStack);

        return result;
    }

startActivityMayWait方法經過調用多次的startActivity方法後會調用到startActivityUnchecked這個方法,那這個方法是幹啥的呢?這個方法會根據啓動標誌位和Activity啓動模式來決定如何啓動一個Activity以及是否要調用deliverNewIntent方法通知Activity有一個Intent試圖重新啓動它。比如我們在一開始將活動設置了FLAG_ACTIVITY_NEW_TASK後將創建一個任務棧,其它的就自行看代碼。

  private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {
...
 if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
                && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
            newTask = true;
            //創建新的TaskRecord
            result = setTaskFromReuseOrCreateNewTask(
                    taskToAffiliate, preferredLaunchStackId, topStack);
        } else if (mSourceRecord != null) {
            result = setTaskFromSourceRecord();
        } else if (mInTask != null) {
            result = setTaskFromInTask();
        } else {
            setTaskToCurrentTopOrCreateNewTask();
        }
       ...
 if (mDoResume) {
            final ActivityRecord topTaskActivity =
                    mStartActivity.getTask().topRunningActivityLocked();
            if (!mTargetStack.isFocusable()
                    || (topTaskActivity != null && topTaskActivity.mTaskOverlay
                    && mStartActivity != topTaskActivity)) {
               ...
            } else {
                if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) {
                    mTargetStack.moveToFront("startActivityUnchecked");
                }
                mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
                        mOptions);
            }
        } else {
            mTargetStack.addRecentActivityLocked(mStartActivity);
        }
        ...

}

然後無論以何種模式啓動最終都會調用ActivityStackSupervisor.resumeFocusedStackTopActivityLocked方法。

frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

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

於是又調用了ActivityStack的resumeTopActivityUncheckedLocked

frameworks/base/services/core/java/com/android/server/am/ActivityStack.java

    @GuardedBy("mService")
    boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
       ...
        try {
            // Protect against recursion.
            mStackSupervisor.inResumeTopActivity = true;
            result = resumeTopActivityInnerLocked(prev, options);
        }
       ...

    }

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
      ...
           mStackSupervisor.startSpecificActivityLocked(next, true, true);
       }
        if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
       return true;
}

emmmm…,看到這估計都懵逼了,幾個類跳來跳去也不知道幹了些什麼,不慌,讓我們堅持看下ActivityStackSupervisor.startSpecificActivityLocked,因爲這個方法很重要。這個方法將是普通Activity和根Activity啓動流程的分岔路口。

ActivityStackSupervisor#startSpecificActivityLocked

    void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
        //獲取即將要啓動的Activity的所在的應用程序進程
        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true);
        //如果應用進程已經存在
        if (app != null && app.thread != null) {
            try {
                if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                        || !"android".equals(r.info.packageName)) {
                    // Don't add this if it is a platform component that is marked
                    // to run in multiple processes, because this is actually
                    // part of the framework so doesn't make sense to track as a
                    // separate apk in the process.
                    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);
            }

            // If a dead object exception was thrown -- fall through to
            // restart the application.
        }
		//應用進程還未創建,則通過AMS調用startProcessLocked向Zygote進程發送請求
        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
    }

閱讀上面的代碼我們可以知道在方法中首先獲取到了即將要啓動的Activity所在的應用進程,假如是普通的Activity的啓動流程的活,這個進程肯定是存在的,所以將執行realStartActivityLocked的方法。但是我們現在討論的是根Activity的啓動流程,由於應用都還未啓動,意味着根Activity所在的應用進程還未創建,而mService其實就是AMS,所以這裏將調用AMS的startProcessLocked。於是我們又回到了最初的起點AMS。

ActivityManagerService.java

    final ProcessRecord startProcessLocked(String processName,
            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
            boolean isolated, boolean keepIfLarge) {
        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
                null /* crashHandler */);
    }

    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
        ...
        final boolean success = startProcessLocked(app, hostingType, hostingNameStr, abiOverride);
        ...
    }

    @GuardedBy("this")
    private final boolean startProcessLocked(ProcessRecord app,
            String hostingType, String hostingNameStr, String abiOverride) {
        return startProcessLocked(app, hostingType, hostingNameStr,
                false /* disableHiddenApiChecks */, abiOverride);
    }

    private final boolean startProcessLocked(ProcessRecord app, String hostingType,
            String hostingNameStr, boolean disableHiddenApiChecks, String abiOverride) {
       ...

            int uid = app.uid; //創建應用進程的用戶ID
            int[] gids = null;
            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
            if (!app.isolated) {
                int[] permGids = null;
                try {
                    checkTime(startTime, "startProcess: getting gids from package manager");
                    final IPackageManager pm = AppGlobals.getPackageManager();
                    permGids = pm.getPackageGids(app.info.packageName,
                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
                            StorageManagerInternal.class);
                    mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
                            app.info.packageName);
                } catch (RemoteException e) {
                    throw e.rethrowAsRuntimeException();
                }

                /*
                 * 對用戶組進行創建和賦值
                 */
                if (ArrayUtils.isEmpty(permGids)) {
                    gids = new int[3];
                } else {
                    gids = new int[permGids.length + 3];
                    System.arraycopy(permGids, 0, gids, 3, permGids.length);
                }
                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
                gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
                gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));

                // Replace any invalid GIDs
                if (gids[0] == UserHandle.ERR_GID) gids[0] = gids[2];
                if (gids[1] == UserHandle.ERR_GID) gids[1] = gids[2];
            }
            ...
            //這個參數後文會提到
            final String entryPoint = "android.app.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) {
            ....
            if (hostingType.equals("webview_service")) {
                startResult = startWebView(entryPoint,
                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, null,
                        new String[] {PROC_START_SEQ_IDENT + app.startSeq});

            } else {

			
				//通過Process.start方法來爲應用創建進程
                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);
        }
    }

是不是又驚呆了,好吧,我也驚呆了!反正就是通過調用多個startProcessLocked方法後最終將調用startProcess方法,不過需要重點看一下上面的第四個startProcessLocked,在該方法中有個entryPoint參數爲 “android.app.ActivityThread”,這個參數將在後文講到創建應用進程後啓動ActivityThread會用到。然後在startProcess方法裏將調用Process.start來發送應用創建進程的請求。這樣AMS就將發送請求的事交給了Process

2.2 Process向Zygote進程發送創建應用進程請求

frameworks/base/core/java/android/os/Process.java

    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 ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids,
                    runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                    abi, instructionSet, appDataDir, invokeWith,
                    /*useBlastulaPool=*/ true, zygoteArgs);
    }


    public final Process.ProcessStartResult start(final String processClass,
                                                  final String niceName,
                                                  int uid, int gid, int[] gids,
                                                  int runtimeFlags, int mountExternal,
                                                  int targetSdkVersion,
                                                  String seInfo,
                                                  String abi,
                                                  String instructionSet,
                                                  String appDataDir,
                                                  String invokeWith,
                                                  boolean useBlastulaPool,
                                                  String[] zygoteArgs) {
        try {

		    //重點關注
            return startViaZygote(processClass, niceName, uid, gid, gids,
                    runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                    abi, instructionSet, appDataDir, invokeWith,
                    /*startChildZygote=*/false,
                    useBlastulaPool, zygoteArgs);
        } catch (ZygoteStartFailedEx ex) {
            Log.e(LOG_TAG,
                    "Starting VM process through Zygote failed");
            throw new RuntimeException(
                    "Starting VM process through Zygote failed", ex);
        }
    }

從上面可以發現,Process中的start方法的實現是startViaZygote方法,所以我們重點觀察下這個方法。

    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,
                                                      boolean useBlastulaPool,
                                                      String[] extraArgs)
                                                      throws ZygoteStartFailedEx {
        ArrayList<String> argsForZygote = new ArrayList<String>();

        // --runtime-args, --setuid=, --setgid=,
        //創建字符串列表argsForZygote,並將啓動應用進程的啓動參數保存在這個列表中
        argsForZygote.add("--runtime-args");
        argsForZygote.add("--setuid=" + uid);
        argsForZygote.add("--setgid=" + gid);
        argsForZygote.add("--runtime-flags=" + runtimeFlags);
        if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) {
            argsForZygote.add("--mount-external-default");
        } else if (mountExternal == Zygote.MOUNT_EXTERNAL_READ) {
            argsForZygote.add("--mount-external-read");
        } else if (mountExternal == Zygote.MOUNT_EXTERNAL_WRITE) {
            argsForZygote.add("--mount-external-write");
        }
        argsForZygote.add("--target-sdk-version=" + targetSdkVersion);

        ...
        synchronized(mLock) {


		    //重點關注
            return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
                                              useBlastulaPool,
                                              argsForZygote);
        }
    }

在startViaZygote中會創建字符串列表argsForZygote來保存將要創建的應用進程的啓動參數,然後最後會調用zygoteSendArgsAndGetResult方法,而在這個方法中第一個參數會調用openZygoteSocketIfNeeded方法,第三個參數就是啓動參數列表。所以我們先看看openZygoteSocketIfNeeded這個方法的實現。

    private ZygoteState openZygoteSocketIfNeeded(String abi)
            throws ZygoteStartFailedEx {

        Preconditions.checkState(Thread.holdsLock(mLock), "ZygoteProcess lock not held");
		//64位進程中的
        if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
            try {


			    //調用ZygoteState的connect函數與mZygoteSocketAddress建立連接,
                //這裏mZygoteSocketAddress的值爲“zygote”
                primaryZygoteState =
                    ZygoteState.connect(mZygoteSocketAddress, mBlastulaPoolSocketAddress);
            } catch (IOException ioe) {
                throw new ZygoteStartFailedEx("Error connecting to primary zygote", ioe);
            }

            maybeSetApiBlacklistExemptions(primaryZygoteState, false);
            maybeSetHiddenApiAccessLogSampleRate(primaryZygoteState);
        }

        if (primaryZygoteState.matches(abi)) {

		    //Socket進行連接成功並匹配abi後會返回ZygoteState類型對象
            return primaryZygoteState;
        }
		

        // 32位Zygote進程中
        if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {
            try {
                secondaryZygoteState =
                    ZygoteState.connect(mZygoteSecondarySocketAddress,
                                        mBlastulaPoolSecondarySocketAddress);
            } catch (IOException ioe) {
                throw new ZygoteStartFailedEx("Error connecting to secondary zygote", ioe);
            }

            maybeSetApiBlacklistExemptions(secondaryZygoteState, false);
            maybeSetHiddenApiAccessLogSampleRate(secondaryZygoteState);
        }

        if (secondaryZygoteState.matches(abi)) {
            return secondaryZygoteState;
        }

        throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
    } 

openZygoteSocketIfNeeded這個方法從方法名就可以推測出這個方法的作用,大概就是與Zygote建立Socket連接。而從代碼中也證實了這一點,在代碼中會根據Zygote進程的位數來建立相應的Socket連接,然後返回ZygoteState類型的對象。既然與Zygote建立好Socket連接後,接下來當然是發送請求啦!所以讓我們來看看zygoteSendArgsAndGetResult這個方法中是如何發送請求的!

	//將傳入的應用進程的啓動參數argsForZygote寫入到ZygoteState
    @GuardedBy("mLock")
    private static Process.ProcessStartResult zygoteSendArgsAndGetResult(
            ZygoteState zygoteState, boolean useBlastulaPool, ArrayList<String> args)
            throws ZygoteStartFailedEx {
        String msgStr = Integer.toString(args.size()) + "\n"
                        + String.join("\n", args) + "\n";

        // Should there be a timeout on this?
        Process.ProcessStartResult result = new Process.ProcessStartResult();

        // TODO (chriswailes): Move branch body into separate function.
        if (useBlastulaPool && Zygote.BLASTULA_POOL_ENABLED && isValidBlastulaCommand(args)) {
            LocalSocket blastulaSessionSocket = null;

            try {
                blastulaSessionSocket = zygoteState.getBlastulaSessionSocket();

                final BufferedWriter blastulaWriter =
                        new BufferedWriter(
                                new OutputStreamWriter(blastulaSessionSocket.getOutputStream()),
                                Zygote.SOCKET_BUFFER_SIZE);
                final DataInputStream blastulaReader =
                        new DataInputStream(blastulaSessionSocket.getInputStream());

                blastulaWriter.write(msgStr);
                blastulaWriter.flush();

                result.pid = blastulaReader.readInt();
                // Blastulas can't be used to spawn processes that need wrappers.
                result.usingWrapper = false;

                if (result.pid < 0) {
                    throw new ZygoteStartFailedEx("Blastula specialization failed");
                }

                return result;
            } catch (IOException ex) {
                // If there was an IOException using the blastula pool we will log the error and
                // attempt to start the process through the Zygote.
                Log.e(LOG_TAG, "IO Exception while communicating with blastula pool - "
                               + ex.toString());
            } finally {
                try {
                    blastulaSessionSocket.close();
                } catch (IOException ex) {
                    Log.e(LOG_TAG, "Failed to close blastula session socket: " + ex.getMessage());
                }
            }
        }

        try {
            final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter;
            final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream;

            zygoteWriter.write(msgStr);
            zygoteWriter.flush();

            // Always read the entire result from the input stream to avoid leaving
            // bytes in the stream for future process starts to accidentally stumble
            // upon.
            result.pid = zygoteInputStream.readInt();
            result.usingWrapper = zygoteInputStream.readBoolean();
        } catch (IOException ex) {
            zygoteState.close();
            Log.e(LOG_TAG, "IO Exception while communicating with Zygote - "
                    + ex.toString());
            throw new ZygoteStartFailedEx(ex);
        }

        if (result.pid < 0) {
            throw new ZygoteStartFailedEx("fork() failed");
        }

        return result;
    }

因爲在openZygoteSocketIfNeeded中我們已經與Zygote進程建立了Socket連接,所以在這個方法中將傳入的應用進程的啓動參數argsForZygote寫入到ZygoteState。這樣AMS就完成了向Zygote進程發送創建應用進程的請求的任務。

三、Zygote進程接受請求並孵化應用進程

從上面我們知道,AMS已經與Zygote進程建立Socket連接併發送了創建應用進程的請求,那麼Zygote進程是在哪裏收到請求,收到請求後又是怎麼處理的呢?這裏可以停下來先看看劉望舒的Android系統啓動流程(二)解析Zygote進程啓動過程,寫的很不錯。不過由於我們分析的源碼基於8.0,可能會稍微不同,但總體上來大致流程是一樣的。通過閱讀後我們知道Zygote進程是在ZygoteInit的main方法中接受請求的。所以現在的入口就是ZygoteInit的main方法。

1. 時序圖

在這裏插入圖片描述

2. 詳細過程

從時序圖與上面的分析我們知道現在Zygote進程接受請求是在main方法,就讓我們來看看這個main方法

frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

    @UnsupportedAppUsage
    public static void main(String argv[]) {
        ZygoteServer zygoteServer = new ZygoteServer();
        Runnable caller;
        try {
            ...
			//創建名爲zygote的Socket
            zygoteServer.createZygoteSocket(socketName);
            ....
			//由於在init.rc中設置了start-system-server參數,因此
			//這裏將啓動SystemServer,可見SystemServer由Zygote創建的第一個進程
            if (startSystemServer) {
                Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
                if (r != null) {
                    r.run();
                    return;
                }
            }
           
            caller = Zygote.initBlastulaPool();
            if (caller == null) {
                Log.i(TAG, "Accepting command socket connections");
                //等待AMS的請求
                caller = zygoteServer.runSelectLoop(abiList);
            }
        } catch (Throwable ex) {
            Log.e(TAG, "System zygote died with exception", ex);
            throw ex;
        } finally {
            zygoteServer.closeServerSocket();
        }

        // We're in the child process and have exited the select loop. Proceed to execute the
        // command.
        if (caller != null) {
            caller.run();
        }
    }

通過main方法,我們可以知道在這個main方法首先要創建一個Server端的Socket,這個name爲”zygote”的Socket用來等待ActivityManagerService來請求Zygote來創建新的應用程序進程,在上面AMS請求的分析中我們也知道客戶端將根據這個name來與Zygote的Socket建立連接。接下去會啓動SystemServer進程,這個進程會啓動各種系統服務,比如與Activity啓動息息相關的AMS。最後會調用ZygoteServer.runSelectLoop(abiList)來使創建的Socket進入無限循環,等待AMS請求。讓我們來看看這個runSelectLoop

frameworks/base/core/java/com/android/internal/os/ZygoteServer.java

    Runnable runSelectLoop(String abiList) {
   
        ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
        peers.add(null);
        while (true) {

            while (--pollIndex >= 0) {
                if ((pollFDs[pollIndex].revents & POLLIN) == 0) {
                    continue;
                }

                if (pollIndex == 0) {
				  //監聽Socket連接,充當服務端Socket
                    ZygoteConnection newPeer = acceptCommandPeer(abiList);
                    peers.add(newPeer);
                    socketFDs.add(newPeer.getFileDescriptor());
                } else if (pollIndex < blastulaPoolEventFDIndex) { 
                    try {
						//不斷處理客戶端的AMS的請求,然後交給processOneCommand
                        ZygoteConnection connection = peers.get(pollIndex);
                        final Runnable command = connection.processOneCommand(this);
                    } 
                    ....
                }
            }
        }
    }

可以發現這個方法是死循環表示不停的監聽着Socket連接。acceptCommandPeer方法就是監聽是否收到了請求,如果收到了請求就交給processOneCommand來實現

frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java

    Runnable processOneCommand(ZygoteServer zygoteServer) {
        String args[];
        ZygoteArguments parsedArgs = null;
        FileDescriptor[] descriptors;
        try {
		    //獲取應用程序進程的啓動參數
            args = Zygote.readArgumentList(mSocketReader);
            // TODO (chriswailes): Remove this and add an assert.
            descriptors = mSocket.getAncillaryFileDescriptors();
        } catch (IOException ex) {
            throw new IllegalStateException("IOException on command socket", ex);
        }
        ....
        parsedArgs = new ZygoteArguments(args);
        ....
		//fork當前進程創建一個子進程
        pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids,
                parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,
                parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
                parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mTargetSdkVersion);

        try {

		    //pid爲0則代表這個進程爲子進程,即新創建的應用程序進程
            if (pid == 0) {
                zygoteServer.setForkChild();
                zygoteServer.closeServerSocket();
                IoUtils.closeQuietly(serverPipeFd);
                serverPipeFd = null;

                return handleChildProc(parsedArgs, descriptors, childPipeFd,
                        parsedArgs.mStartChildZygote);
            } 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);
        }
    }

在這個方法中將對請求進行處理,首先獲取到將要啓動的應用進程的啓動參數,然後調用forkAndSpecialize來創建應用進程。

frameworks/base/core/java/com/android/internal/os/Zygote.java

    public static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFlags,
            int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
            int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir,
            int targetSdkVersion) {
        ZygoteHooks.preFork();
        // Resets nice priority for zygote process.
        resetNicePriority();
        int pid = nativeForkAndSpecialize(
                uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
                fdsToIgnore, startChildZygote, instructionSet, appDataDir);
        // Enable tracing as soon as possible for the child process.
        if (pid == 0) {
            Zygote.disableExecuteOnly(targetSdkVersion);
            Trace.setTracingEnabled(true, runtimeFlags);

            // Note that this event ends at the end of handleChildProc,
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork");
        }
        ZygoteHooks.postForkCommon();
        return pid;
    }

在forkAndSpecialize中,最終將創建應用進程的任務交給nativeForkAndSpecialize,而這個方法可以看出來應該是本地方法,所以具體如何創建的我們就不深究了,在這裏我們這需要知道nativeForkAndSpecialize最終是通過fork當前進程來創建一個子進程,而fork後會有返回值給pid:

  • 父進程中,fork返回新創建的子進程pid;
  • 子進程中,fork返回0;
  • 出現錯誤時,fork返回負數。

於是到這裏子進程也就是應用進程就被孵化出來了。你以爲這樣就結束了?其實還早呢!別忘了我們的最終使命是根Activity的啓動,而現在只是有了根Activity所需要的應用進程,革命尚未成功,仍需要努力!

四、應用進程啓動ActivityThread

1. 時序圖

在這裏插入圖片描述

2. 詳細過程

從上面我們知道應用進程已經被創建,那創建後呢?這就需要我們回頭看上面的processOneCommand方法,細心的你肯定會發現再孵化出應用進程後,還是有返回值的。

frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java

    Runnable processOneCommand(ZygoteServer zygoteServer) {
        ....
		//fork當前進程創建一個子進程
        pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids,
                parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,
                parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
                parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mTargetSdkVersion);

        try {

		    //pid爲0則代表這個進程爲子進程,即新創建的應用程序進程
            if (pid == 0) {
                ....
                return handleChildProc(parsedArgs, descriptors, childPipeFd,
                        parsedArgs.mStartChildZygote);
            } else {
                ...
            }
        }
        ....
    }

在上面我們分析了當pid=0的時候,則代表了當前進程已經是子進程了,即應用進程。所以下一步將執行handleChildProc方法。

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

而handleChildProc最終又會調用ZygoteInit.zygoteInit方法。如下

frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

    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();
		//爲當前的VM設置未捕獲異常器
        RuntimeInit.commonInit();
		//Binder驅動初始化,該方法完成後,可通過Binder進行進程通信
        ZygoteInit.nativeZygoteInit();
		//主要調用SystemServer的main方法
        return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
    }

在這個方法裏會創建當前進程的Binder線程池,便於後續與其它進程通信,然後調用了RuntimeInit的applicationInit方法,如下:

frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

   protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
            ClassLoader classLoader) {
        ...
        final Arguments args = new Arguments(argv);
        // Remaining arguments are passed to the start class's static main
        return findStaticMain(args.startClass, args.startArgs, classLoader);
    }

這個方法最終會調用findStaticMain方法,不過需注意的是方法的第一個參數args.startClass其實就是我們上文AMS將請求任務轉移給Process中在最後強調的那個參數:android.app.ActivityThread。然後我們看看findStaticMain的實現

    protected static Runnable findStaticMain(String className, String[] argv,
            ClassLoader classLoader) {
        Class<?> cl;
        try {
            cl = Class.forName(className, true, classLoader);//1
        } catch (ClassNotFoundException ex) {
           ....
        }
        Method m;
        try {
            m = cl.getMethod("main", new Class[] { String[].class });//2
        } catch (NoSuchMethodException ex) {
            ...
        } catch (SecurityException ex) {
            ...
        }
        return new MethodAndArgsCaller(m, argv);
    }

在這個方法中首先在註釋1通過反射獲取到android.app.ActivityThread類,然後在註釋2獲取到ActivityThread的main方法,最後通過main方法來構造MethodAndArgsCaller。而這個MethodAndArgsCaller是什麼呢?如下:

frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

static class MethodAndArgsCaller implements Runnable {
        /** method to call */
        private final Method mMethod;

        /** argument array */
        private final String[] mArgs;

        public MethodAndArgsCaller(Method method, String[] args) {
            mMethod = method;
            mArgs = args;
        }

        public void run() {
            try {
                mMethod.invoke(null, new Object[] { mArgs });
            } catch (IllegalAccessException ex) {
                throw new RuntimeException(ex);
            } catch (InvocationTargetException ex) {
                Throwable cause = ex.getCause();
                if (cause instanceof RuntimeException) {
                    throw (RuntimeException) cause;
                } else if (cause instanceof Error) {
                    throw (Error) cause;
                }
                throw new RuntimeException(ex);
            }
        }
    }

追蹤下去,MethodAndArgsCaller其實是RuntimeInit的一個內部類並且繼承了Runnable,然後在run方法中會通過反射調用了mMethod方法,此時mMethod是ActivityThread的main方法,即run方法中將會執行ActivityThread的main方法,在這裏你可能會有疑問了,那這個run方法什麼時候執行呢?讓我們來看看最開始的ZygoteInit的main方法。

frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

    @UnsupportedAppUsage
    public static void main(String argv[]) {
        Runnable caller;
        try {
           ....
            caller = Zygote.initBlastulaPool();
            if (caller == null) {
                Log.i(TAG, "Accepting command socket connections");
                //等待AMS的請求
                caller = zygoteServer.runSelectLoop(abiList);
            }
        } catch (Throwable ex) {
            Log.e(TAG, "System zygote died with exception", ex);
            throw ex;
        } finally {
            zygoteServer.closeServerSocket();
        }
        if (caller != null) {
            caller.run();
        }
    }

有沒有恍然大悟呢?從分析Zygote進程接受請求並孵化應用進程的一開始,我們就是分析zygoteServer.runSelectLoop(abiList)這個方法,而分析到最後findStaticMain方法將返回MethodAndArgsCaller對象(繼承Runnable),所以這時候在ZygoteInit的main方法caller會等於這個MethodAndArgsCaller對象,顯然caller不等於null,故最後會執行caller.run方法,即執行ActivityThread的main方法。於是應用進程成功啓動ActivityThread。

後續

分析到這,我們已經越來越接近萬里長征的終點了!不過還是得歇歇,養足精力,才能走到終點。下篇博客Android之9.0Activity啓動流程(二)將分析Activity啓動流程的剩下部分。即:

  • 應用進程綁定到AMS
  • AMS發送啓動Activity的請求
  • ActivityThread的Handler處理啓動Activity的請求

參考博客:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章