Launcher启动流程
1、AMS的systemReady()
上回讲述了《Android系统启动流程》,当系统在Framework层经过一系列多种语言程序有来有回之后,系统服务会被其中,其中包括AMS,startOtherServices()方法执行后阶段,各种被启动起来的Service会各种掉systemReady();其中AMS的systemReady就会被调用,这时候就是告诉应用层说我系统准备好了,SystemServer爸爸要撤了。
SystemServer.java
private void startOtherServices() {
... 省略 摘要
try {
// TODO: use boot phase
mPowerManagerService.systemReady(mActivityManagerService.getAppOpsService());
mPackageManagerService.systemReady();
mDisplayManagerService.systemReady(safeMode, mOnlyCore);
} catch (Throwable e) {
}
mActivityManagerService.systemReady(new Runnable()){
...
}
wm.systemReady();
...
}
1.ActiviyManagerService -> systemReady()
public void systemReady(final Runnable goingCallback) {
。。。
// Check to see if there are any update receivers to run.
if (!mDidUpdate) {
if (mWaitingUpdate) {
return;
}
//除非已升级,如果检测没有做过升级,则启动升级
mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
public void run() {
synchronized (ActivityManagerService.this) {
mDidUpdate = true;
}
showBootMessage(mContext.getText(
R.string.android_upgrading_complete),
false);
writeLastDonePreBootReceivers(doneReceivers);
systemReady(goingCallback);
}
}, doneReceivers, UserHandle.USER_OWNER);
if (mWaitingUpdate) {
return;
}
mDidUpdate = true;
}
mAppOpsService.systemReady();
mSystemReady = true;
}
retrieveSettings();
loadResourcesOnSystemReady();
synchronized (this) {
readGrantedUriPermissionsLocked();
}
// Start up initial activity.
mBooting = true;
//Launcher启动
startHomeActivityLocked(mCurrentUserId, "systemReady");
mStackSupervisor.resumeTopActivitiesLocked();
//切换其他程序退到后台
sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
}
}
可以看到在AMS systemReady()里接着启动了HomeActivity,这时候将要第一个先把Launcher的主程序唤起来。
2.ActiviyManagerService -> startHomeActivityLocked()
boolean startHomeActivityLocked(int userId, String reason) {
/** 1.创建一个到达Home的Intent action:android.intent.action.MAIN category:android.intent.category.HOME */
Intent intent = getHomeIntent();
//2.resolveActivityInfo查找出对应的activityinfo
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);
//3.启动Activity
mStackSupervisor.startHomeActivity(intent, aInfo, reason);
}
}
return true;
}
里面1、3步不用介绍了,就是创建Intent和启动Activity的流程,具体来看看
resolveActivityInfo()怎么查找到对应的ActivityInfo的
2.ActiviyManagerService -> resolveActivityInfo()
private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
ActivityInfo ai = null;
ComponentName comp = intent.getComponent();
try {
if (comp != null) {
// Factory test.
ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
} else {
ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
intent,
intent.resolveTypeIfNeeded(mContext.getContentResolver()),
flags, userId);
if (info != null) {
ai = info.activityInfo;
}
}
} catch (RemoteException e) {
// ignore
}
return ai;
}
可以看到,从AppGlobals里请出我们熟悉的PackageManager出来搞事了
//1获取IPackageManager接口来查找intent
AppGlobals.getPackageManager().resolveIntent()
//2.第一步实际是跟ActivityThread获取的,而源头是跟ServiceManager获取的,实现类是ApplicationPackageManager
ActivityThread.getPackageManager()
接下来是弄明白ApplicationPackageManager和PackageManagerService的关系,这是只用一句话是通过IPackageManager接口来进行Binder通讯。具体的实现业务是在PackageManagerService,这里因为Binder的panda先不扩展细节了。
PackageManagerService -> resolveIntent()
@Override
public ResolveInfo resolveIntent(Intent intent, String resolvedType,
int flags, int userId) {
if (!sUserManager.exists(userId)) return null;
enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "resolve intent");
List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
return chooseBestActivity(intent, resolvedType, flags, query, userId);
}
到这里,ActivityInfo的源头就找到了。流程大致为AMS创建Intent,PMS帮忙查找到ActivityInfo,然后ActivityStack拿着ActivityInfo金钥匙准备启动HomeActivity桌面
2、AMS启动Launcher
mStackSupervisor.startHomeActivity(intent, aInfo, reason);
这里做了三件事:
void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason) {
//1、将Home任务排到栈顶
moveHomeStackTaskToTop(HOME_ACTIVITY_TYPE, reason);
//2、启动Activity
startActivityLocked(null /* caller */, intent, null /* resolvedType */, aInfo,
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 (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.
//3.刚好如果已在Home了,那就直接前置
scheduleResumeTopActivities();
}
}
总结一下:
1、SystemServer启动完所有Boot服务,Core服务、Other服务,就通知所有服务systemReady();
2、其中在AMS的systemReady()里就做了启动Launcher。
3、启动Launcher做了三步:创建Intent;让PMS帮忙通过Binder通讯查找ActivityInfo;让ActivityStack启动Activity。
(后续分享
1.系统级Binder机制的构建过程和在系统中的作用。2.context.startActivity()干了哪些事情)