持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第16天,点击查看活动详情
前言
上篇文章我们提到了Launcher进程,我们探究到了从Launcher桌面的icon点击到startActivity中间到底发生了什么,Launcher进程本身也是一个App,那么Android是如何启动我们的桌面应用的,了解了这个,我们就可以大致了解Launcher进程是如何通过进程间通信启动别的app了.
一、Zygote
通过前几篇文章的分析,我们已经大致知道init进程首先启动了Zygote进程,Zygote承担着孵化进程的任务,它第一个孵化的进程就是SystemeServer进程.SystemServer进程,SystemServer进程又启动了AMS,WMS,PWS,InputManager等主要的辅助服务.
二、SystemServer
2.1 main()
public final class SystemServer {
public static void main(String[] args) {
new SystemServer().run();
}
public SystemServer() {
// Check for factory test mode.
mFactoryTestMode = FactoryTest.getMode();
// Remember if it's runtime restart(when sys.boot_completed is already set) or reboot
mRuntimeRestart = "1".equals(SystemProperties.get("sys.boot_completed"));
}
}
这个主函数做了初始化的设置,设置了是否从boot开机之后的标识位.
2.2 run()
private void run() {
//1.记录好native上来的虚拟机参数
...
Looper.prepareMainLooper();
// Initialize native services.
//初始化的android_servers.so包里面包含了大量的native的android服务
System.loadLibrary("android_servers");
// Check whether we failed to shut down last time we tried.
// This call may not return.
performPendingShutdown();
// Initialize the system context.
createSystemContext();
// Create the system service manager.
mSystemServiceManager = new SystemServiceManager(mSystemContext);
mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
// Start services.
try {
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices");
startBootstrapServices();
startCoreServices();
startOtherServices();
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
// For debug builds, log event loop stalls to dropbox for analysis.
if (StrictMode.conditionallyEnableDebugLogging()) {
Slog.i(TAG, "Enabled StrictMode for system server main thread.");
}
// Loop forever.
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
run方法里主要做了四件事.
- 1、记录从zygote过来的虚拟机等runtime参数,初始化android_server的so库,android_server初始化了重要的系统服务的native层.
- 2、为SystemServer设置Looper,并进入到loop的循环,等待其他应用的调用.
- 3、初始化SystemServer的context以及初始化SystemServiceManager
- 4、启动各大主要的系统服务.
2.3 createSystemContext
在初始化SystemServer之前,调用了systemMain()方法初始化了ActivityThread
同时为系统设置了默认主题
private void createSystemContext() {
ActivityThread activityThread = ActivityThread.systemMain();
mSystemContext = activityThread.getSystemContext();
mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
}
2.4 SystemServiceManager
// Create the system service manager.
mSystemServiceManager = new SystemServiceManager(mSystemContext);
mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
- 1、SystemServiceManager作为所有Android服务的启动者和控制者,启动后被加入到了LocalServices中
- 2、LocalServices的作用,实际上和SystemServiceManager的作用很相似,LocalService的内部有一个ArrayMap,直接保存着对应服务的实例
而SystemServiceManager往往通过反射,直接调用Context参数的构造函数.
三、 启动各大服务
// Start services.
try {
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices");
startBootstrapServices();
startCoreServices();
startOtherServices();
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
可以看到,在声明了SystemServiceManager之后,调用了很多启用服务的方法.
3.1 startBootstrapServices
private void startBootstrapServices() {
// Wait for installd to finish starting up so that it has a chance to
// create critical directories such as /data/user with the appropriate
// permissions. We need this to complete before we initialize other services.
Installer installer = mSystemServiceManager.startService(Installer.class);
// Activity manager runs the show.
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
// Power manager needs to be started early because other services need it.
// Native daemons may be watching for it to be registered so it must be ready
// to handle incoming binder calls immediately (including being able to verify
// the permissions for those calls).
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
// Now that the power manager has been started, let the activity manager
// initialize power management features.
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "InitPowerManagement");
mActivityManagerService.initPowerManagement();
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
// Manages LEDs and display backlight so we need it to bring up the display.
mSystemServiceManager.startService(LightsService.class);
// Display manager is needed to provide display metrics before package manager
// starts up.
mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
// We need the default display before we can initialize the package manager.
mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
// Only run "core" apps if we're encrypting the device.
String cryptState = SystemProperties.get("vold.decrypt");
if (ENCRYPTING_STATE.equals(cryptState)) {
Slog.w(TAG, "Detected encryption in progress - only parsing core apps");
mOnlyCore = true;
} else if (ENCRYPTED_STATE.equals(cryptState)) {
Slog.w(TAG, "Device encrypted - only parsing core apps");
mOnlyCore = true;
}
// Start the package manager.
traceBeginAndSlog("StartPackageManagerService");
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
mFirstBoot = mPackageManagerService.isFirstBoot();
mPackageManager = mSystemContext.getPackageManager();
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
// Manages A/B OTA dexopting. This is a bootstrap service as we need it to rename
// A/B artifacts after boot, before anything else might touch/need them.
// Note: this isn't needed during decryption (we don't have /data anyways).
if (!mOnlyCore) {
boolean disableOtaDexopt = SystemProperties.getBoolean("config.disable_otadexopt",
false);
if (!disableOtaDexopt) {
traceBeginAndSlog("StartOtaDexOptService");
try {
OtaDexoptService.main(mSystemContext, mPackageManagerService);
} catch (Throwable e) {
reportWtf("starting OtaDexOptService", e);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
}
}
traceBeginAndSlog("StartUserManagerService");
mSystemServiceManager.startService(UserManagerService.LifeCycle.class);
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
// Initialize attribute cache used to cache resources from packages.
AttributeCache.init(mSystemContext);
// Set up the Application instance for the system process and get started.
mActivityManagerService.setSystemProcess();
// The sensor service needs access to package manager service, app ops
// service, and permissions service, therefore we start it after them.
startSensorService();
}
- 1、Install在SystemServer端,等待installd的服务通过Binder连接进来。接着这个installd会通过installd.rc读取脚本,生成一个installd的进程,该进程的作用是用来安装软件用的
- 2、ActivityManagerService就是我们最熟悉的AMS了,贯穿整个App应用的服务,负责的主要功能就是管理启动的Activity,同时把install这个服务装载进去.
- 3、PowerManagerService是负责协助管理电源的服务.
- 4、LightService控制手机的灯的设备
- 5、DisplayManagerService从4.2开始作为手机管理显示的服务.
- 6、PackageManagerService管理app应用的package的信息.
- 7、UserManagerService,早期Android是一个单用户系统,当Android成为了多用户系统,而多用户就是通过这个类去管理
- 8、SensorService,传感器的初始化.
3.2 startCoreServices
/**
* Starts some essential services that are not tangled up in the bootstrap process.
*/
private void startCoreServices() {
// Tracks the battery level. Requires LightService.
mSystemServiceManager.startService(BatteryService.class);
// Tracks application usage stats.
mSystemServiceManager.startService(UsageStatsService.class);
mActivityManagerService.setUsageStatsManager(
LocalServices.getService(UsageStatsManagerInternal.class));
// Tracks whether the updatable WebView is in a ready state and watches for update installs.
mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class);
}
- 1.启动了BatteryService,主要用于监控电池,电量信息的服务
- 2、UsageStatsManagerInternal监控应用服务,常用的应用如检测应用使用时间等.
- 3、如果打开了webview标识位,则启动webview的更新服务
3.3 startOtherServices
private void startOtherServices() {
...
try {
wm.systemReady();
} catch (Throwable e) {
reportWtf("making Window Manager Service ready", e);
}
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
if (safeMode) {
mActivityManagerService.showSafeModeOverlay();
}
// Update the configuration for this context by hand, because we're going
// to start using it before the config change done in wm.systemReady() will
// propagate to it.
Configuration config = wm.computeNewConfiguration();
DisplayMetrics metrics = new DisplayMetrics();
...
// We now tell the activity manager it is okay to run third party
// code. It will call back into us once it has gotten to the state
// where third party code can really run (but before it has actually
// started launching the initial applications), for us to complete our
// initialization.
mActivityManagerService.systemReady(new Runnable() {
}
}
在这里初始化了许多其他服务,如Inputmanager,network等等,剩下系统的调用服务都将会在这里实现.
四、AMS
public void systemReady(final Runnable goingCallback) {
...
//添加进程列表
ArrayList<ProcessRecord> procsToKill = null;
synchronized(mPidsSelfLocked) {
for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
ProcessRecord proc = mPidsSelfLocked.valueAt(i);
if (!isAllowedWhileBooting(proc.info)){
if (procsToKill == null) {
procsToKill = new ArrayList<ProcessRecord>();
}
procsToKill.add(proc);
}
}
}
startHomeActivityLocked(currentUserId, "systemReady");
....
}
SystemeServer在startOtherServices中调用了AMS的systemReady方法,并且塞入了一个callback
而在AMS的systemReady方法中将当前的进程配置到AMS进程列表中,初始化了PMS,为后续启动Home界面读取Launcher目录下的界面App做准备,最后获取UserController获取当前用户id,使用startHomeActivityLocked开始创建Home界面
4.1 startHomeActivityLocked
boolean startHomeActivityLocked(int userId, String reason) {
if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
&& mTopAction == null) {
// We are running in factory test mode, but unable to find
// the factory test app, so just sit around displaying the
// error message and don't try to start anything.
return false;
}
Intent intent = getHomeIntent();
ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
if (aInfo != null) {
intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
// Don't do this if the home app is currently being
// instrumented.
aInfo = new ActivityInfo(aInfo);
aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
ProcessRecord app = getProcessRecordLocked(aInfo.processName,
aInfo.applicationInfo.uid, true);
if (app == null || app.instrumentationClass == null) {
intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
}
} else {
Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
}
return true;
}
4.1.1 getHomeIntent
Intent getHomeIntent() {
Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
intent.setComponent(mTopComponent);
intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
intent.addCategory(Intent.CATEGORY_HOME);
}
return intent;
}
第一步,通过getHomeIntent()创建一个有效的intent,并且获取对应的ActivityInfo
而这个getHomeIntent会给其添加一个Intent.CATEGORY_HOME的标识位
4.1.2 resolveActivityInfo
resolveActivityInfo()方法通过Binder跨进程通知PMS从系统已安装的应用中,找到一个符合HomeIntent的Activity.
private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
ActivityInfo ai = null;
//系统正常启动时,component为null
ComponentName comp = intent.getComponent();
try {
if (comp != null) {
// Factory test.
ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
} else {
//resolveIntent做了两件事
//1.通过queryIntentActivities来查找符合HomeIntent需求的Activities
//2.通过chooseBaseActivity找到最符合Intent需求的Activity信息
ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
intent,
intent.resolveTypeIfNeeded(mContext.getContentResolver()),
flags, userId);
if (info != null) {
ai = info.activityInfo;
}
}
} catch (RemoteException e) {
// ignore
}
return ai;
}
/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
@Override
public ResolveInfo resolveIntent(Intent intent, String resolvedType,
int flags, int userId) {
try {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
if (!sUserManager.exists(userId)) return null;
flags = updateFlagsForResolve(flags, userId, intent);
enforceCrossUserPermission(Binder.getCallingUid(), userId,
false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
flags, userId);
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
final ResolveInfo bestChoice =
chooseBestActivity(intent, resolvedType, flags, query, userId);
return bestChoice;
} finally {
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
}
4.2 startHomeActivityLocked
mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
void startHomeActivityLocked(Intent intent, ActivityInfo aInfo, String reason) {
mSupervisor.moveHomeStackTaskToTop(HOME_ACTIVITY_TYPE, reason);
startActivityLocked(null /*caller*/, intent, null /*ephemeralIntent*/,
null /*resolvedType*/, aInfo, null /*rInfo*/, null /*voiceSession*/,
null /*voiceInteractor*/, null /*resultTo*/, null /*resultWho*/,
0 /*requestCode*/, 0 /*callingPid*/, 0 /*callingUid*/, null /*callingPackage*/,
0 /*realCallingPid*/, 0 /*realCallingUid*/, 0 /*startFlags*/, null /*options*/,
false /*ignoreTargetSecurity*/, false /*componentSpecified*/, null /*outActivity*/,
null /*container*/, null /*inTask*/);
if (mSupervisor.inResumeTopActivity) {
// If we are in resume section already, home activity will be initialized, but not
// resumed (to avoid recursive resume) and will stay that way until something pokes it
// again. We need to schedule another resume.
mSupervisor.scheduleResumeTopActivities();
}
}
关键方法是 moveHomeStackTaskToTop以及scheduleResumeTopActivities
4.3 moveHomeStackTaskToTop
void moveHomeStackTaskToTop(int homeStackTaskType) {
final int top = mTaskHistory.size() - 1;
for (int taskNdx = top; taskNdx >= 0; --taskNdx) {
final TaskRecord task = mTaskHistory.get(taskNdx);
if (task.taskType == homeStackTaskType) {
if (DEBUG_TASKS || DEBUG_STACK) Slog.d(TAG_STACK,
"moveHomeStackTaskToTop: moving " + task);
mTaskHistory.remove(taskNdx);
mTaskHistory.add(top, task);
updateTaskMovement(task, true);
return;
}
}
}
先从TaskHistory任务栈中取出顶部Activity,如果此时Activity栈有Activity的存在,则把Home的Activity更新到顶部
4.4 scheduleResumeTopActivities
final void scheduleResumeTopActivities() {
if (!mHandler.hasMessages(RESUME_TOP_ACTIVITY_MSG)) {
mHandler.sendEmptyMessage(RESUME_TOP_ACTIVITY_MSG);
}
}
此时由AMS内部的handler接收消息
case RESUME_TOP_ACTIVITY_MSG: {
synchronized (mService) {
resumeFocusedStackTopActivityLocked();
}
} break;
这个handler就是在SystemServer生成的looper传进来,其中RESUME_TOP_ACTIVITY_MSG的分支将会调用resumeFocusedStackTopActivityLocked
4.5 resumeFocusedStackTopActivityLocked
boolean resumeFocusedStackTopActivityLocked() {
return resumeFocusedStackTopActivityLocked(null, null, null);
}
boolean resumeFocusedStackTopActivityLocked(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
if (targetStack != null && isFocusedStack(targetStack)) {
return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
if (r == null || r.state != RESUMED) {
mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
}
return false;
}
此时将会判断到,当前栈对应的ActivityRecord是否存在,此时是第一次打开的,所以此时ActivityRecord还没有生成,将会走到resumeTopActivityUncheckedLocked
4.6 resumeTopActivityUncheckedLocked
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions 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;
}
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
if (DEBUG_LOCKSCREEN) mService.logLockScreen("");
if (!mService.mBooting && !mService.mBooted) {
// Not ready yet!
return false;
}
...
} else {
// Whoops, need to restart this activity!
if (!next.hasBeenLaunched) {
next.hasBeenLaunched = true;
} else {
if (SHOW_APP_STARTING_PREVIEW) {
next.showStartingWindow(null, true);
}
if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);
}
if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);
mStackSupervisor.startSpecificActivityLocked(next, true, true);
}
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
return true;
}
此时由于必定不存在Activity,此时必定通过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);
}
4.7 startProcessLocked
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
private final void startProcessLocked(ProcessRecord app,
String hostingType, String hostingNameStr) {
startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
null /* entryPoint */, null /* entryPointArgs */);
}
private final void startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
long startTime = SystemClock.elapsedRealtime();
...
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);
....
在这里通过Process.start创建了新的进程,新的进程又会导入ActivityThread类,并执行它的main函数
这一阶段主要检查activity所在的进程是否存在,如果存在,就直接通知这个进程,在该进程中启动这个Activity,不存在的话,会调用Process.start创建一个新进程(执行在AMS进程)
至此我们的Launcher进程就被创建,接下来就是创建ActivityThread和 ApplicationThread了