Android Launcher启动应用程序流程源码解析

带着问题看源码

  1. 点击桌面Launcher图标后作了哪些工做?
  2. 应用程序何时被建立的?
  3. Application和MainActivity的onCreate()方法何时被调用的?

概述

Android系统中,启动四大组件中的任何一个均可以启动应用程序。但绝大部分时候咱们是经过点击Launcher图标启动应用程序。本文依据Android6.0源码,从点击Launcher图标,直至解析到MainActivity#OnCreate()被调用。java

Launcher简析

Launcher也是个应用程序,不过是个特殊的应用。俗称“桌面”。经过PackageManagerService查询全部已安装的应用程序,并保存相应的图标、应用名称、包名和第一个要启动的类名等。android

源码位置:frameworks/base/core/Java/android/app/LauncherActivity.java数组

LauncherActivity#onListItemClick()服务器

public abstract class LauncherActivity extends ListActivity {
    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        Intent intent = intentForPosition(position);
        startActivity(intent);
    }
}
  •  

能够看到LauncherActivity继承自ListActivity,而ListActivity继承自Activity。在LauncherActivity#onListItemClick()方法中首先经过intentForPosition()获取了一个Intent,而后调用startActivity(intent)启动一个Activity。因为ListActivity并无重写Activity#startActivity()方法,因此这里会直接调用Activity#startActivity()。在此以前先看下intentForPosition()是怎样构造Intentapp

protected Intent intentForPosition(int position) {
        ActivityAdapter adapter = (ActivityAdapter) mAdapter;
        return adapter.intentForPosition(position);
    }

    private class ActivityAdapter extends BaseAdapter implements Filterable {
        public Intent intentForPosition(int position) {
            if (mActivitiesList == null) {
                return null;
            }
            Intent intent = new Intent(mIntent);
            ListItem item = mActivitiesList.get(position);
            intent.setClassName(item.packageName, item.className);
            if (item.extras != null) {
                intent.putExtras(item.extras);
            }
            return intent;
        }
    }
  •  

Intent中只是指定了即将启动的Activitysocket

源码位置:frameworks/base/core/java/android/app/Activity.javaasync

Activity#startActivity()ide

public void startActivity(Intent intent) {
        this.startActivity(intent, null);
    }

    public void startActivity(Intent intent, @Nullable Bundle options) {
        if (options != null) {
            startActivityForResult(intent, -1, options);
        } else {
            startActivityForResult(intent, -1);
        }
    }

    /** @param requestCode If >= 0, this code will be returned inonActivityResult() when the activity exits. */
    public void startActivityForResult(Intent intent, int requestCode) {
        startActivityForResult(intent, requestCode, null);
    }

    public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
            Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
           ...
        }
    }
  •  

在调用的过程当中能够观察到,不管调用StartActivity()仍是startActivityForResult(),最终调用的都是startActivityForResult()。并且注释说明只有requestCode >= 0onActivityResult()才会被调用。通过一系列的调用,最终调用了Instrumentation#execStartActivity()。跟进。oop

源码位置:frameworks/base/core/java/android/app/Instrumentation.javapost

Instrumentation#execStartActivity()

public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target, 
        Intent intent, int requestCode, Bundle options) {
            ...
            int result = ActivityManagerNative.getDefault()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
            ...
    }

这里ActivityManagerNative.getDefault()涉及到Binder进程间通讯机制。下面进行一个简短的介绍,这不是本文的重点。了解过同窗的能够略过下面这段Binder简析,不想了解的也能够直接理解为返回的是ActivityManagerService(如下简称AMS)。实际调用的是AMS#startActivity()

AMS中Binder机制简析

ActivityManagerNative.getDefault()

static public IActivityManager getDefault() {
        return gDefault.get();
    }

    private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            IBinder b = ServiceManager.getService("activity");
            IActivityManager am = asInterface(b);
            return am;
        }
    };

    static public IActivityManager asInterface(IBinder obj) {
        if (obj == null) {
            return null;
        }
        IActivityManager in =
            (IActivityManager)obj.queryLocalInterface(descriptor);
        if (in != null) {
            return in;
        }

        return new ActivityManagerProxy(obj);
    }
  •  

本例中AMS做为服务器端,ActivityManagerNative做为客户端。在getDefault()方法中经过调用asInterface()方法中的new ActivityManagerProxy(obj)返回了IActivityManager的子类对象AMS。从哪里能够看出来呢?这个就比较难找了,不过细心点仍是能够发现写蛛丝马迹。重点在于IBinder b = ServiceManager.getService("activity"),这里的参数是“activity”。在上篇博文SystemServer启动流程源码解析中,分析SystemServer#startBootstrapServices()方法启动AMS以后调用mActivityManagerService.setSystemProcess(),跟进。

源码位置:frameworks/base/services/java/com/android/server/SystemServer.java

SystemServer#startBootstrapServices()

private void startBootstrapServices() {
        Installer installer = mSystemServiceManager.startService(Installer.class);

        // Activity manager runs the show.
        mActivityManagerService = mSystemServiceManager.startService(
                ActivityManagerService.Lifecycle.class).getService();
        mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
        mActivityManagerService.setInstaller(installer);
        // Set up the Application instance for the system process and get started.
        mActivityManagerService.setSystemProcess();
    }

    public void setSystemProcess() {
        ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
    }
  •  

静态常量Context.ACTIVITY_SERVICE = "activity"。到这里就对上了。先addService("activity"),而后getService("activity")。其实在add和get的时候,又是一次经过Binder进行进程间通讯的过程。此次和本文关系不大,这里再也不拓展。下面回到AMS#startActivity()

调用过程解析

前方高能,可能会致使身体感到严重不适。请作好心理准备!

源码位置:frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

ActivityManagerService#startActivity()

@Override
    public final int startActivity(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
            resultWho, requestCode, startFlags, profilerInfo, options,
            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 options, int userId) {
        // 验证CallingUid是否合法
        enforceNotIsolatedCaller("startActivity");
        // 检查限权
        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
                false, ALLOW_FULL_ONLY, "startActivity", null);
        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
                profilerInfo, null, null, options, false, userId, null, null);
    }
  •  

简单验证后开始调用StackSupervisor#startActivityMayWait(),跟进。 
源码位置:frameworks/base/services/core/java/com/android/server/am/StackSupervisor.java

StackSupervisor#startActivityMayWait()、StackSupervisor#resolveActivity()

final 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 config,
                                   Bundle options, boolean ignoreTargetSecurity, int userId,
                                   IActivityContainer iContainer, TaskRecord inTask) {
          ...
         // 解析intent信息                         
         ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags, profilerInfo, userId);
         // 验证pid uid(省略)
         ...
        int res = startActivityLocked(caller, intent, resolvedType, aInfo,
                voiceSession, voiceInteractor, resultTo, resultWho,
                requestCode, callingPid, callingUid, callingPackage,
                realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity,
                componentSpecified, null, container, inTask);

        return res;                          
    }

    ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags,
                                 ProfilerInfo profilerInfo, int userId) {
        // Collect information about the target of the Intent.
        ActivityInfo aInfo;
        try {
            ResolveInfo rInfo = AppGlobals.getPackageManager().resolveIntent(
                            intent, resolvedType,
                            PackageManager.MATCH_DEFAULT_ONLY 
                            | ActivityManagerService.STOCK_PM_FLAGS, userId);
            aInfo = rInfo != null ? rInfo.activityInfo : null;
        } catch (RemoteException e) {
            aInfo = null;
        }

        if (aInfo != null) {
            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
            ...
        }
        return aInfo;
    }
  •  

在调用resolveActivity()以后会读取配置文件中包名和要启动Activity完整的路径名,并分别赋值给aInfo.applicationInfo.packageName和aInfo.name。跟进。

StackSupervisor#startActivityLocked()

final int startActivityLocked(IApplicationThread caller,
                                  Intent intent, String resolvedType, ActivityInfo aInfo,
                                  IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                                  IBinder resultTo, String resultWho, int requestCode,
                                  int callingPid, int callingUid, String callingPackage,
                                  int realCallingPid, int realCallingUid, int startFlags, Bundle options,
                                  boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
                                  ActivityContainer container, TaskRecord inTask) {
        ProcessRecord callerApp = null;
        if (caller != null) {
            callerApp = mService.getRecordForAppLocked(caller);
            if (callerApp != null) {
                callingPid = callerApp.pid;
                callingUid = callerApp.info.uid;
            } else {
                err = ActivityManager.START_PERMISSION_DENIED;
            }
        }
        ...
        ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
                intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
                requestCode, componentSpecified, voiceSession != null, this, container, options);
        // 检查intent中的flag信息
        ...
        // 检查限权
        ...
        ...
        err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,
                startFlags, true, options, inTask);
        return err;

    }
  •  

这个方法近300行代码,咱们只看关键的部分就行了。首先获取调用者的pid、uid等信息,而后保存在callerApp中。目标Activity的信息保存在 r 中。跟进。

StackSupervisor#startActivityUncheckedLocked()

final int startActivityUncheckedLocked(final ActivityRecord r, ActivityRecord sourceRecord,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags,
        boolean doResume, Bundle options, TaskRecord inTask) {
        ...
        int launchFlags = intent.getFlags();
        // 对intent的flag各类判断
        ...
        ActivityRecord notTop = (launchFlags & Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
        ...
                ActivityStack sourceStack;
        if (sourceRecord != null) {
            if (sourceRecord.finishing) {
                if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
                    Slog.w(TAG, "startActivity called from finishing " + sourceRecord
                            + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
                    launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
                    newTaskInfo = sourceRecord.info;
                    newTaskIntent = sourceRecord.task.intent;
                }
                sourceRecord = null;
                sourceStack = null;
            } else {
                sourceStack = sourceRecord.task.stack;
            }
        } else {
            sourceStack = null;
        }
        ...
        if (((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
                (launchFlags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
                || launchSingleInstance || launchSingleTask) {
            if (inTask == null && r.resultTo == null) {
                // See if there is a task to bring to the front.  If this is
                // a SINGLE_INSTANCE activity, there can be one and only one
                // instance of it in the history, and it is always in its own
                // unique task, so we do a special search.
                ActivityRecord intentActivity = !launchSingleInstance ?
                        findTaskLocked(r) : findActivityLocked(intent, r.info);
        ...
        }
        ...
        // Should this be considered a new task?
        if (r.resultTo == null && inTask == null && !addingToTask
                && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
            newTask = true;
            targetStack = computeStackFocus(r, newTask);
            targetStack.moveToFront("startingNewTask");

            if (reuseTask == null) {
                // 设任务栈
                r.setTask(targetStack.createTaskRecord(getNextTaskId(),
                        newTaskInfo != null ? newTaskInfo : r.info,
                        newTaskIntent != null ? newTaskIntent : intent,
                        voiceSession, voiceInteractor, !launchTaskBehind /* toTop */),
                        taskToAffiliate);
            } 
            ...
        }
        ...
        targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
        return ActivityManager.START_SUCCESS;
    }
  •  

这个方法600+行,并且好多逻辑判断,看的几近崩溃。不过还好,关键的代码已经被过滤出来了~首先肯定几个变量。前面都没有设置过intentflag,因此launchFlags = 0x00000000,可是在执行launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK以后。launchFlags = Intent.FLAG_ACTIVITY_NEW_TASKnotTop = null。因为没有要接收返回信息的Activity,因此r.resultTo == null。因为没有设置Activity的启动模式为SingleInstance,因此launchSingleInstance = false,即会执行findTaskLocked(r)。这个方法的做用是查找历史全部stack中有没有目标Activity,很显然返回值为null,因此下面很大一段判断逻辑都不会执行。大约200行,爽~。既然没有相应的任务栈,确定要建立的。在上文中建立任务栈对应的方法为targetStack.createTaskRecord()。最后执行ActivityStack#startActivityLocked(),跟进。

源码位置:frameworks/base/services/core/java/com/android/server/am/ActivityStack.java

ActivityStack#startActivityLocked()

final void startActivityLocked(ActivityRecord r, boolean newTask,
            boolean doResume, boolean keepCurTransition, Bundle options) {
        ...
        // newTask = true
        if(!newTask){
            ...
        }
        task = r.task;
        // 将ActivityRecord置于栈顶
        task.addActivityToTop(r);
        // 将任务栈置于前台
        task.setFrontOfTask();
        ...
        if (doResume) {
            mStackSupervisor.resumeTopActivitiesLocked(this, r, options);
        }
    }
  •  

跟进。

源码位置:frameworks/base/services/core/java/com/android/server/am/StackSupervisor.java

StackSupervisor#resumeTopActivitiesLocked()

boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
                                      Bundle targetOptions) {
        if (targetStack == null) {
            targetStack = mFocusedStack;
        }
        // Do targetStack first.
        boolean result = false;
        if (isFrontStack(targetStack)) {
            result = targetStack.resumeTopActivityLocked(target, targetOptions);
        }

        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                final ActivityStack stack = stacks.get(stackNdx);
                if (stack == targetStack) {
                    // Already started above.
                    continue;
                }
                if (isFrontStack(stack)) {
                    stack.resumeTopActivityLocked(null);
                }
            }
        }
        return result;
    }
  •  

这个方法的做用是将Launcher应用程序所在的任务栈执行resumeTopActivityLocked()方法。跟进。

源码位置:frameworks/base/services/core/java/com/android/server/am/ActivityStack.java

ActivityStack#resumeTopActivityLocked()

final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
        if (mStackSupervisor.inResumeTopActivity) {
            // Don't even start recursing.
            return false;
        }

        boolean result = false;
        try {
            // Protect against recursion.
            mStackSupervisor.inResumeTopActivity = true;
            if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {
                mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;
                mService.updateSleepIfNeededLocked();
            }
            result = resumeTopActivityInnerLocked(prev, options);
        } finally {
            mStackSupervisor.inResumeTopActivity = false;
        }
        return result;
    }
  •  

跟进。

ActivityStack#resumeTopActivityInnerLocked()

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {
        ...
        // If the top activity is the resumed one, nothing to do.
        if (mResumedActivity == next && next.state == ActivityState.RESUMED &&
                    mStackSupervisor.allResumedActivitiesComplete()) {
            ...
            return false;
        }
        ...
        if (mResumedActivity != null) {
            if (DEBUG_STATES) Slog.d(TAG_STATES,
                    "resumeTopActivityLocked: Pausing " + mResumedActivity);
            pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
        }
        ...
        mStackSupervisor.startSpecificActivityLocked(next, true, true);
        ...
    }
  •  

这个方法的主要做用是将mResumedActivity暂停(Launcher任务栈的TopActivity),即进入onPause状态。以后启动指定的AttivityRecored,即target AttivityRecored

源码位置:frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

ActivityStackSupervisor#startSpecificActivityLocked()

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

        r.task.stack.setLaunchTime(r);

        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.versionCode,
                            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.
        }

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

因为没有在指定Applicationprocess属性,因此这里的app = null

详见ActivityStackSupervisor#getProcessRecordLocked()

final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
        if (uid == Process.SYSTEM_UID) {
            // The system gets to run in any process.  If there are multiple
            // processes with the same uid, just pick the first (this
            // should never happen).
            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
            if (procs == null) return null;
            ...
        }
        ...
    }
  •  

跟进。

源码位置:frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

ActivityManagerService#startProcessLocked()

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 */);
    }
  •  

跟进。

ActivityManagerService#startProcessLocked()

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) {
        // isolated = false
        if (!isolated) {
            // 没有指定application的process,因此app = null
            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
            ...
        }
        ...
        if (app == null) {
            checkTime(startTime, "startProcess: creating new process record");
            // 建立ProcessRecord
            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
            ...
            checkTime(startTime, "startProcess: done creating new process record");
        }
    }
        ...
        checkTime(startTime, "startProcess: stepping in to startProcess");
        // hostingNameStr="activity" 后面仨参数都是null
        startProcessLocked(
                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
        checkTime(startTime, "startProcess: done starting proc!");
  •  

终于看见Process的身影了,亲人呐!!!

ActivityManagerService#startProcessLocked()

private final void startProcessLocked(ProcessRecord app, String hostingType,
            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
            ...
        try {
            int uid = app.uid;
            int[] gids = null;
            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
            // isolated = false
            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, app.userId);
                    MountServiceInternal mountServiceInternal = LocalServices.getService(
                            MountServiceInternal.class);
                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
                            app.info.packageName);
                } catch (RemoteException e) {
                    throw e.rethrowAsRuntimeException();
                }

                /*
                 * Add shared application and profile GIDs so applications can share some
                 * resources like shared libraries and access user-wide resources
                 */
                if (ArrayUtils.isEmpty(permGids)) {
                    gids = new int[2];
                } else {
                    gids = new int[permGids.length + 2];
                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
                }
                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
            }
            ...
            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
            if (requiredAbi == null) {
                requiredAbi = Build.SUPPORTED_ABIS[0];
            }

            String instructionSet = null;
            if (app.info.primaryCpuAbi != null) {
                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
            }

            app.gids = gids;
            app.requiredAbi = requiredAbi;
            app.instructionSet = instructionSet;

            checkTime(startTime, "startProcess: asking zygote to start proc");
            Process.ProcessStartResult startResult = Process.start(entryPoint,
                    app.processName, uid, uid, gids, debugFlags, mountExternal,
                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
                    app.info.dataDir, entryPointArgs);
            checkTime(startTime, "startProcess: returned from zygote!");
            ...
        }
        ...
    }
  •  

这个方法过重要了,因此展现的代码稍微多一些。首先肯定几个参数值。hostingType = activity、后面的三个参数abiOverrideentryPointentryPointArgs均等于nullapp.isolated = false。首先建立了gids[]这个参数,而后在前两项插入AppGidUserGid,而后构造了requiredAbiinstructionSet等参数,以后调用Process#start()来建立新进程。Process#start()。如今是凌晨两点,若是你像我同样已经写了5个小时,必定会发现这方法名字是多么的让人陶醉~

抽只烟冷静下~

跟进。

源码位置:frameworks/base/core/java/android/os/Process.java

Process#start()

public static final ProcessStartResult start(final String processClass,
                                  final String niceName,
                                  int uid, int gid, int[] gids,
                                  int debugFlags, int mountExternal,
                                  int targetSdkVersion,
                                  String seInfo,
                                  String abi,
                                  String instructionSet,
                                  String appDataDir,
                                  String[] zygoteArgs) {
        try {
            return startViaZygote(processClass, niceName, uid, gid, gids,
                    debugFlags, mountExternal, targetSdkVersion, seInfo,
                    abi, instructionSet, appDataDir, zygoteArgs);
        } catch (ZygoteStartFailedEx ex) {
            Log.e(LOG_TAG,
                    "Starting VM process through Zygote failed");
            throw new RuntimeException(
                    "Starting VM process through Zygote failed", ex);
        }
    }
  •  

这是只是调用startViaZygote()进一步处理。跟进。

Process#startViaZygote()

private static ProcessStartResult startViaZygote(final String processClass,
                                  final String niceName,
                                  final int uid, final int gid,
                                  final int[] gids,
                                  int debugFlags, int mountExternal,
                                  int targetSdkVersion,
                                  String seInfo,
                                  String abi,
                                  String instructionSet,
                                  String appDataDir,
                                  String[] extraArgs)
                                  throws ZygoteStartFailedEx {
        synchronized(Process.class) {
            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);
            ...
                        // --setgroups is a comma-separated list
            if (gids != null && gids.length > 0) {
                StringBuilder sb = new StringBuilder();
                sb.append("--setgroups=");

                int sz = gids.length;
                for (int i = 0; i < sz; i++) {
                    if (i != 0) {
                        sb.append(',');
                    }
                    sb.append(gids[i]);
                }

                argsForZygote.add(sb.toString());
            }

            if (niceName != null) {
                argsForZygote.add("--nice-name=" + niceName);
            }

            if (seInfo != null) {
                argsForZygote.add("--seinfo=" + seInfo);
            }

            if (instructionSet != null) {
                argsForZygote.add("--instruction-set=" + instructionSet);
            }

            if (appDataDir != null) {
                argsForZygote.add("--app-data-dir=" + appDataDir);
            }

            argsForZygote.add(processClass);

            if (extraArgs != null) {
                for (String arg : extraArgs) {
                    argsForZygote.add(arg);
                }
            }
            return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
        }
    }
  •  

能够看到,这里前面一大段都在构造参数argsForZygoteuid啦、gid啦、-nice-name啦,这里须要注意processClass = android.app.ActivityThread,后文会用到。参数构造完成以后,接下来看下openZygoteSocketIfNeeded()这个方法。

Process#openZygoteSocketIfNeeded()

/**
     * Tries to open socket to Zygote process if not already open. If
     * already open, does nothing.  May block and retry.
     */
    private static ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
        if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
            try {
                primaryZygoteState = ZygoteState.connect(ZYGOTE_SOCKET);
            } catch (IOException ioe) {
                throw new ZygoteStartFailedEx("Error connecting to primary zygote", ioe);
            }
        }

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

        // The primary zygote didn't match. Try the secondary.
        if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {
            try {
            secondaryZygoteState = ZygoteState.connect(SECONDARY_ZYGOTE_SOCKET);
            } catch (IOException ioe) {
                throw new ZygoteStartFailedEx("Error connecting to secondary zygote", ioe);
            }
        }

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

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

罕见的我把注释写上了,由于注释说的比我清楚~接下来跟进zygoteSendArgsAndGetResult()方法。

Process#zygoteSendArgsAndGetResult()

/**
     * Sends an argument list to the zygote process, which starts a new child
     * and returns the child's pid. Please note: the present implementation
     * replaces newlines in the argument list with spaces.
     *
     * @throws ZygoteStartFailedEx if process start failed for any reason
     */
    private static ProcessStartResult zygoteSendArgsAndGetResult(
            ZygoteState zygoteState, ArrayList<String> args)
            throws ZygoteStartFailedEx {
        try {
            /**
             * See com.android.internal.os.ZygoteInit.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.
             */
            final BufferedWriter writer = zygoteState.writer;
            final DataInputStream inputStream = zygoteState.inputStream;

            writer.write(Integer.toString(args.size()));
            writer.newLine();

            int sz = args.size();
            for (int i = 0; i < sz; i++) {
                String arg = args.get(i);
                if (arg.indexOf('\n') >= 0) {
                    throw new ZygoteStartFailedEx(
                            "embedded newlines not allowed");
                }
                writer.write(arg);
                writer.newLine();
            }

            writer.flush();

            // Should there be a timeout on this?
            ProcessStartResult result = new ProcessStartResult();
            result.pid = inputStream.readInt();
            if (result.pid < 0) {
                throw new ZygoteStartFailedEx("fork() failed");
            }
            result.usingWrapper = inputStream.readBoolean();
            return result;
        } catch (IOException ex) {
            zygoteState.close();
            throw new ZygoteStartFailedEx(ex);
        }
    }
  •  

注释也说的很清楚,给Zygote发送一个argument list。通知Zygote进程启动一个子进程。再接下来就该和Zygote进程打交道了。

太晚了,关键明天还要上班。明天再细致分析这部分,古耐~

大哥大Zygote

在另外一篇博文 Android Zygote启动流程源码解析中说到:在Zygote#main()中先注册了一个serverSocket,在启动了SystemServer进程以后,一直监听这个serverSocket,准备启动新的应用进程。大概过程以下:

源码位置:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

ZygoteInit#main()

public static void main(String argv[]) {
    // 注册socket
    registerZygoteSocket(socketName);
    ...
    if (startSystemServer) {
        // 启动SystemServer进程
        startSystemServer(abiList, socketName);
    }
    // 监听socket,启动新的应用进程。--后文会讲
    runSelectLoop(abiList);
    closeServerSocket();
    ...
}
  •  

跟进runSelectLoop(abiList)

ZygoteInit#runSelectLoop()

private static void runSelectLoop(String abiList) throws MethodAndArgsCaller {
        while (true) {
            int index;
            ...
            if (index < 0) {
                throw new RuntimeException("Error in select()");
            } else if (index == 0) {
                ZygoteConnection newPeer = acceptCommandPeer(abiList);
                peers.add(newPeer);
                fds.add(newPeer.getFileDescriptor());
            } else {
                boolean done;
                done = peers.get(index).runOnce();

                if (done) {
                    peers.remove(index);
                    fds.remove(index);
                }
            }
        }   
    }

    private static ZygoteConnection acceptCommandPeer(String abiList) {
        try {
            return new ZygoteConnection(sServerSocket.accept(), abiList);
        } catch (IOException ex) {
            ...
        }
    }
  •  

这个方法的主要做用是经过acceptCommandPeer()方法接收客户端发送的Socket消息。以后执行ZygoteConnection#runOnce()方法。跟进。

源码位置:frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java

ZygoteConnection#runOnce()

boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {
        ...
        checkTime(startTime, "zygoteConnection.runOnce: preForkAndSpecialize");
        pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
                    parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
                    parsedArgs.niceName, fdsToClose, parsedArgs.instructionSet,
                    parsedArgs.appDataDir);
        checkTime(startTime, "zygoteConnection.runOnce: postForkAndSpecialize");
        ...
        if (pid == 0) {
            // in child
            IoUtils.closeQuietly(serverPipeFd);
            serverPipeFd = null;
            handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);
                // should never get here, the child is expected to either
                // throw ZygoteInit.MethodAndArgsCaller or exec().
                return true;
            } else {
               ...
            }
            ...
    }
  •  

省略的一大段代码都在构造参数,以后根据参数调用Zygote.forkAndSpecialize()方法fork出应用程序进程,到这里,应用进程已经被建立了。由于是子进程pid = 0,因此以后会调用handleChildProc()方法进一步处理。跟进。

ZygoteConnection#handleChildProc()

private void handleChildProc(Arguments parsedArgs,
            FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr)
            throws ZygoteInit.MethodAndArgsCaller {
        closeSocket();
        ZygoteInit.closeServerSocket();
        ...
        ZygoteInit.invokeStaticMain(cloader, className, mainArgs);
        ...
    }
  •  

上述代码先关闭从Zygote进程继承来的ServerSocket,而后调用ZygoteInit.invokeStaticMain()。接下来的流程和启动System进程流程差很少,这里快速的过一遍。不熟悉这部分的同窗能够参考这篇博客

源码位置:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

ZygoteInit#invokeStaticMain()

static void invokeStaticMain(ClassLoader loader, String className, String[] argv)
            throws ZygoteInit.MethodAndArgsCaller {
        Class<?> cl;
        try {
            cl = loader.loadClass(className);
        } catch (ClassNotFoundException ex) {
            throw new RuntimeException(
                    "Missing class when invoking static main " + className, ex);
        }
        Method m;
        m = cl.getMethod("main", new Class[] { String[].class });
        int modifiers = m.getModifiers();
        if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
            throw new RuntimeException(
                    "Main method is not public and static on " + className);
        }
        throw new ZygoteInit.MethodAndArgsCaller(m, argv);
    }
  •  

意料之中的装载类文件、意料之中的反射、意料之中的验证修饰符、意料之中的抛出个异常,甚至意料之中的在Zygote#main()中捕获。看过Zygote启动流程源码解析的读着确定和我有同样的感受。接下来就该捕获异常,而后反射ActivityThread的静态方法main()。直接贴代码了,so boring…

ZygoteInit#main()

public static void main(String argv[]) {
        try {
            ...
            runSelectLoop(abiList);
        } catch (MethodAndArgsCaller caller) {
            caller.run();
        }

        // ZygoteInit&MethodAndArgsCaller#run()
        public void run() {
            try {
                mMethod.invoke(null, new Object[] { mArgs });
            } catch (IllegalAccessException ex) {
                ...
            } 
        }
  •  

这里反射调用的是ActivityThread#main()方法。跟进。

主进程的建立流程

源码位置:frameworks/base/core/java/com/android/app/ActivityThread.java

ActivityThread#main()

public static void main(String[] args) {
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
        SamplingProfilerIntegration.start();
        ...
        Looper.prepareMainLooper();
        ActivityThread thread = new ActivityThread();
        thread.attach(false);

        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }
        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }
  •  

咱们知道ActivityThread就是所谓的主线程,其实ActivityThread并非一个主线程。只是一个拥有mainLooper的入口方法。

概述中说:在Android系统中,启动四大组件中的任何一个均可以启动应用程序。启动四大组件的均可以启动应用程序,但实际上入口方法只有ActivityThread#main()一个(未验证)。

在作了一些初始化的工做后,调用了ActivityThread#attach(false)。跟进。

final ApplicationThread mAppThread = new ApplicationThread();

    private void attach(boolean system) {
        sCurrentActivityThread = this;
        mSystemThread = system;
        if (!system) {
            ...
            final IActivityManager mgr = ActivityManagerNative.getDefault();
            try {
                mgr.attachApplication(mAppThread);
            } catch (RemoteException ex) {
                // Ignore
            }
            ...
        }
        ...
    }
  •  

前文AMS中的Binder机制中分析过:ActivityManagerNative.getDefault(),返回的是AMS。其中跟进。

源码位置:frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

ActivityManagerService#attachApplication()

public final void attachApplication(IApplicationThread thread) {
        synchronized (this) {
            int callingPid = Binder.getCallingPid();
            final long origId = Binder.clearCallingIdentity();
            attachApplicationLocked(thread, callingPid);
            Binder.restoreCallingIdentity(origId);
        }
    }
  •  

这里只是调用两个参数的attachApplicationLocked()方法处理。跟进。

private final boolean attachApplicationLocked(IApplicationThread thread,int pid) {
        ...
        if (normalMode) {
            try {
                if (mStackSupervisor.attachApplicationLocked(app)) {
                    didSomething = true;
                }
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                badApp = true;
            }
        }
        ...
    }
  •  

跟进。

源码位置:frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

ActivityStackSupervisor#attachApplicationLocked()

boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
        final String processName = app.processName;
        boolean didSomething = false;
        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                final ActivityStack stack = stacks.get(stackNdx);
                if (!isFrontStack(stack)) {
                    continue;
                }
                ActivityRecord hr = stack.topRunningActivityLocked(null);
                if (hr != null) {
                    if (hr.app == null && app.uid == hr.info.applicationInfo.uid
                            && processName.equals(hr.processName)) {
                        try {
                            if (realStartActivityLocked(hr, app, true, true)) {
                                didSomething = true;
                            }
                        } catch (RemoteException e) {
                            ...
                        }
                    }
                }
            }
        }
        ...
        return didSomething;
    }
  •  

首先遍历全部stack,以后找到目前被置于前台的stack。以后经过topRunningActivityLocked()获取最上面的Activity。最后调用realStartActivityLocked()方法来真正的启动目标Activity。跟进

源码位置:frameworks/base/services/java/com/android/server/am/ActivityStack.java

ActivityStack#realStartActivityLocked()

final boolean realStartActivityLocked(ActivityRecord r,
            ProcessRecord app, boolean andResume, boolean checkConfig)
            throws RemoteException {
        ...
                    app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                    System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
                    r.compat, r.launchedFromPackage, r.task.voiceInteractor, app.repProcState,
                    r.icicle, r.persistentState, results, newIntents, !andResume,
                    mService.isNextTransitionForward(), profilerInfo);
    }
    ...
  •  

这里经过Binder,会调用ApplicationThread#scheduleLaunchActivity()。跟进。

源码位置:frameworks/base/core/java/android/app/ActivityThread.java

ActivityThread&ApplicationThread#scheduleLaunchActivity()

public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
                ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
                CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
                int procState, Bundle state, PersistableBundle persistentState,
                List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
                boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {

            updateProcessState(procState, false);
            ActivityClientRecord r = new ActivityClientRecord();
            r.token = token;
            r.ident = ident;
            r.intent = intent;
            r.referrer = referrer;
            r.voiceInteractor = voiceInteractor;
            r.activityInfo = info;
            r.compatInfo = compatInfo;
            r.state = state;
            ...
            sendMessage(H.LAUNCH_ACTIVITY, r);
        }
  •  

构造一个ActivityClientRecord对象以后,调用sendMessage(H.LAUNCH_ACTIVITY, r)。跟进。

private void sendMessage(int what, Object obj) {
        sendMessage(what, obj, 0, 0, false);
    }

    private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
        if (DEBUG_MESSAGES) Slog.v(
            TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
            + ": " + arg1 + " / " + obj);
        Message msg = Message.obtain();
        msg.what = what;
        msg.obj = obj;
        msg.arg1 = arg1;
        msg.arg2 = arg2;
        if (async) {
            msg.setAsynchronous(true);
        }
        mH.sendMessage(msg);
    }
  •  

根据参数组装了一个Message对象,以后经过mH.sendMessage(msg)发送出去。看下mH是个什么鬼。跟进。

ActivityThread、ActivityThread&H

public final class ActivityThread {
    ...
    final H mH = new H();
    ...
        private class H extends Handler {
        public static final int LAUNCH_ACTIVITY         = 100;
        public static final int PAUSE_ACTIVITY          = 101;
        ...
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case LAUNCH_ACTIVITY: {
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
                    final ActivityClientRecord r = (ActivityClientRecord) msg.obj;

                    r.packageInfo = getPackageInfoNoCheck(
                            r.activityInfo.applicationInfo, r.compatInfo);
                    handleLaunchActivity(r, null);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                } break;
                ...
            }
        }
    }
}
  •  

原来mH不过是Handler的子类罢了。接着在handleMessage()中解析出Message对象,而后调用handleLaunchActivity()进一步处理。跟进。

ActivityThread#handleLaunchActivity()

private final void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {  
        ......  
        // 加载activity,而后调用onCreate,onStart方法
        Activity a = performLaunchActivity(r, customIntent);  
        if (a != null) {
            // 调用onResume方法
            handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed);
            ...   
        }
        ... 
    }
  •  

这是个蛮重要的方法。Activity启动流程源码解析里有详细讲解,这里暂时略过。 
跟进。

ActivityThread#performLaunchActivity()

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");

        ActivityInfo aInfo = r.activityInfo;
        if (r.packageInfo == null) {
            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                    Context.CONTEXT_INCLUDE_CODE);
        }

        ComponentName component = r.intent.getComponent();
        if (component == null) {
            component = r.intent.resolveActivity(
                mInitialApplication.getPackageManager());
            r.intent.setComponent(component);
        }

        if (r.activityInfo.targetActivity != null) {
            component = new ComponentName(r.activityInfo.packageName,
                    r.activityInfo.targetActivity);
        }

        Activity activity = null;
        try {
            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            StrictMode.incrementExpectedActivityCount(activity.getClass());
            r.intent.setExtrasClassLoader(cl);
            r.intent.prepareToEnterProcess();
            if (r.state != null) {
                r.state.setClassLoader(cl);
            }
        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to instantiate activity " + component
                    + ": " + e.toString(), e);
            }
        }

        try {
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);

            if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
            if (localLOGV) Slog.v(
                    TAG, r + ": app=" + app
                    + ", appName=" + app.getPackageName()
                    + ", pkg=" + r.packageInfo.getPackageName()
                    + ", comp=" + r.intent.getComponent().toShortString()
                    + ", dir=" + r.packageInfo.getAppDir());

            if (activity != null) {
                Context appContext = createBaseContextForActivity(r, activity);
                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
                Configuration config = new Configuration(mCompatConfiguration);
                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
                        + r.activityInfo.name + " with config " + config);
                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);

                if (customIntent != null) {
                    activity.mIntent = customIntent;
                }
                r.lastNonConfigurationInstances = null;
                activity.mStartedActivity = false;
                int theme = r.activityInfo.getThemeResource();
                if (theme != 0) {
                    activity.setTheme(theme);
                }

                activity.mCalled = false;
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
                if (!activity.mCalled) {
                    throw new SuperNotCalledException(
                        "Activity " + r.intent.getComponent().toShortString() +
                        " did not call through to super.onCreate()");
                }
                r.activity = activity;
                r.stopped = true;
                if (!r.activity.mFinished) {
                    activity.performStart();
                    r.stopped = false;
                }
                if (!r.activity.mFinished) {
                    if (r.isPersistable()) {
                        if (r.state != null || r.persistentState != null) {
                            mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
                                    r.persistentState);
                        }
                    } else if (r.state != null) {
                        mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
                    }
                }
                if (!r.activity.mFinished) {
                    activity.mCalled = false;
                    if (r.isPersistable()) {
                        mInstrumentation.callActivityOnPostCreate(activity, r.state,
                                r.persistentState);
                    } else {
                        mInstrumentation.callActivityOnPostCreate(activity, r.state);
                    }
                    if (!activity.mCalled) {
                        throw new SuperNotCalledException(
                            "Activity " + r.intent.getComponent().toShortString() +
                            " did not call through to super.onPostCreate()");
                    }
                }
            }
            r.paused = true;

            mActivities.put(r.token, r);

        } catch (SuperNotCalledException e) {
            throw e;

        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to start activity " + component
                    + ": " + e.toString(), e);
            }
        }

        return activity;
    }
  •  

由于这个方法比较重要,因此代码完整的贴出来了。能够看到,首先收集要启动的Activity信息。而后经过ClassLoader加载目标Activiy类。再而后建立Application,最后调用Activity#onCreate()。内容有些多,咱们一步步的看。先从建立Application提及。r.packageInfoLoadedApk对象,因此会调用LoadedApk#makeApplication()

源码位置:frameworks/base/core/java/android/app/LoadedApk.java

LoadedApk#makeApplication()

public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
        if (mApplication != null) {
            return mApplication;
        }

        Application app = null;
        ...
        try {
            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
            app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
        } catch (Exception e) {
            ...
        }
        ...
        if (instrumentation != null) {
            try {
                instrumentation.callApplicationOnCreate(app);
            } catch (Exception e) {
                ...
                }
            }
        }
        return app;
    }
  •  

方法名称已经很明显了。跟进。

源码位置:frameworks/base/core/java/android/app/Instrumentation.java

Instrumentation#newApplication()

public Application newApplication(ClassLoader cl, String className, Context context)
            throws InstantiationException, IllegalAccessException, 
            ClassNotFoundException {
        return newApplication(cl.loadClass(className), context);
    }

    static public Application newApplication(Class<?> clazz, Context context)
            throws InstantiationException, IllegalAccessException, 
            ClassNotFoundException {
        Application app = (Application)clazz.newInstance();
        app.attach(context);
        return app;
    }
  •  

简单粗暴,经过反射建立一个Application实例。如今实例有了,但onCreate()方法尚未被调用。跟进Instrumentation#callApplicationOnCreate()

public void callApplicationOnCreate(Application app) {
        app.onCreate();
    }
  •  

这都无法解析了,,直接调用Application#onCreate()。如今已经有了Application,但Activity只是被ClassLoader装载了,onCreate()尚未调起来。回到ActivityThread#performLaunchActivity()

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

        mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
        ...
  •  

跟进。

源码位置:frameworks/base/core/java/android/app/callActivityOnCreate.java

Instrumentation#callActivityOnCreate()

public void callActivityOnCreate(Activity activity, Bundle icicle,
            PersistableBundle persistentState) {
        prePerformCreate(activity);
        activity.performCreate(icicle, persistentState);
        postPerformCreate(activity);
    }

    // Activity#performCreate()
    final void performCreate(Bundle icicle) {
        onCreate(icicle);
        mActivityTransitionState.readState(icicle);
        performCreateCommon();
    }
  •  

Activity#performCreate()这里调用了OnCreate()方法。终于把咱们的应用程序启动起来了~

总结

整体流程

  1. Launcher经过Binder机制通知AMS启动一个Activity
  2. AMS使Launcher栈最顶端Activity进入onPause状态
  3. AMS通知Process使用Socket和Zygote进程通讯,请求建立一个新进程
  4. Zygote收到Socket请求,fork出一个进程,并调用ActivityThread#main()
  5. ActivityThread经过Binder通知AMS启动应用程序
  6. AMS通知ActivityStackSupervisor真正的启动Activity
  7. ActivityStackSupervisor通知ApplicationThread启动Activity
  8. ApplicationThread发消息给ActivityThread,须要启动一个Activity
  9. ActivityThread收到消息以后,通知LoadedApk建立Applicaition,而且调用其onCteate()方法
  10. ActivityThread装载目标Activity类,并调用Activity#attach()
  11. ActivityThread通知Instrumentation调用Activity#onCreate()
  12. Instrumentation调用Activity#performCreate(),在Activity#performCreate()中调用自身onCreate()方法

第一次启动应用程序,Application和Activity#onCreate()方法调用顺序

  1. 装载Activity
  2. 装载Application
  3. Application#attach()
  4. Application#onCreate()
  5. Activity#attach()
  6. Activity#onCreate()
相关文章
相关标签/搜索