在Android系统中,启动四大组件中的任何一个均可以启动应用程序。但绝大部分时候咱们是经过点击Launcher图标启动应用程序。本文依据Android6.0源码,从点击Launcher图标,直至解析到MainActivity#OnCreate()被调用。java
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()
是怎样构造Intent
。app
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
中只是指定了即将启动的Activity
。socket
源码位置: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 >= 0
时onActivityResult()
才会被调用。通过一系列的调用,最终调用了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()
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+行,并且好多逻辑判断,看的几近崩溃。不过还好,关键的代码已经被过滤出来了~首先肯定几个变量。前面都没有设置过intent
的flag
,因此launchFlags = 0x00000000
,可是在执行launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK
以后。launchFlags = Intent.FLAG_ACTIVITY_NEW_TASK
。notTop = 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); }
因为没有在指定Application
的process
属性,因此这里的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
、后面的三个参数abiOverride
、entryPoint
和entryPointArgs
均等于null
、app.isolated = false
。首先建立了gids[]
这个参数,而后在前两项插入AppGid
和UserGid
,而后构造了requiredAbi
、instructionSet
等参数,以后调用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); } }
能够看到,这里前面一大段都在构造参数argsForZygote
,uid
啦、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
进程打交道了。
太晚了,关键明天还要上班。明天再细致分析这部分,古耐~
在另外一篇博文 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.packageInfo
是LoadedApk
对象,因此会调用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()
方法。终于把咱们的应用程序启动起来了~