目录
前言
记录下一下Launcher是啥时候启动,至于启动中所有步骤这里不细写。
记录于此,主要是方便自己的。
PS : 分析源码 Android 9.0(P)
正文
正常情况下,Launcher是Android中第一个启动的应用。Launcher是Android系统的桌面,也是提供进入其他应用的启动程序。
Launcher很重要,因此今天记录一下Launcher的启动过程。
进入正题。
SystemServer.java
frameworks\base\services\java\com\android\server\SystemServer.java
SystemServer是Zygote启动时fork出来的,而SystemServer中主要的工作是:
初始化环境,比如时间,时区,语言等 准备主线程Looper 加载libandroid_servers.so库 初始化系统Context 创建SystemServiceManager 启动服务(引导服务,核心服务,其他服务) 进入Looper循环
之前大概介绍过(《》),如果需要的可以回归看看。(其实我也忘了,,尴尬)
今天介绍的Launcher启动是在启动服务(引导服务,核心服务,其他服务)中的[其他服务]中启动的。
startOtherServices()
差不多最后,有调用mActivityManagerService.systemReady()
//略[内容很多省略]
mActivityManagerService.systemReady(() -> {
//略
mSystemServiceManager.startBootPhase(
SystemService.PHASE_ACTIVITY_MANAGER_READY);
//略
});
ActivityManagerService.java
frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java
public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
synchronized(this) {
//mSystemReady = false,
if (mSystemReady) {
//略
}
//略[初始化]
mSystemReady = true;
}
//略
final PowerManagerInternal pmi = LocalServices.getService(PowerManagerInternal.class);
//pmi不为null
if (pmi != null) {
pmi.registerLowPowerModeObserver(ServiceType.FORCE_BACKGROUND_CHECK,
state -> updateForceBackgroundCheck(state.batterySaverEnabled));
updateForceBackgroundCheck(
pmi.getLowPowerState(ServiceType.FORCE_BACKGROUND_CHECK).batterySaverEnabled);
}
//略
synchronized (this) {
//为true
if (!android.os.Bolt.BOLT_PERSIST_APP) {
startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
}
mBooting = true;
//略
//BOLT_EARLY_HOME为false,进入
if (!android.os.Bolt.BOLT_EARLY_HOME) {
//进入这里
startHomeActivityLocked(currentUserId, "systemReady");
}
//略
}
}
startHomeActivityLocked
boolean startHomeActivityLocked(int userId, String reason) {
//略[下面部分也省略]
//这里没有获取到Launcher的启动包名
Intent intent = getHomeIntent();
//根据getHomeIntent()中的intent进行获取Launcher包名信息
ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
//aInfo不为null
if (aInfo != null) {
//设置启动包名和启动Activity
intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
aInfo = new ActivityInfo(aInfo);
aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
ProcessRecord app = getProcessRecordLocked(aInfo.processName,
aInfo.applicationInfo.uid, true);
//app == null
if (app == null || app.instr == null) {
intent.setFlags(intent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
//正式启动Launcher的Activity
mActivityStartController.startHomeActivity(intent, aInfo, myReason);
}
}
return true;
}
getHomeIntent()
Intent getHomeIntent() {
Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
//mTopComponent为null
intent.setComponent(mTopComponent);
intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
//添加CATEGORY_HOME属性
if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
intent.addCategory(Intent.CATEGORY_HOME);
}
return intent;
}
这里获取的intent并没有Launcher的启动包名信息,而是:
Intent { act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x100 }
resolveActivityInfo()
private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
ActivityInfo ai = null;
ComponentName comp = intent.getComponent();
try {
//comp为null,因为之前没有获取到
if (comp为null != null) {
// Factory test.
ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
} else {
//进入这里,根据[android.intent.category.HOME]进行获取
ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
intent,
intent.resolveTypeIfNeeded(mContext.getContentResolver()),
flags, userId);
if (info != null) {
ai = info.activityInfo;
}
}
//ai= ActivityInfo{4bb04fb com.biumall.launcher.MainActivity}
} catch (RemoteException e) {
}
return ai;
}
startHomeActivity
void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason) {
mSupervisor.moveHomeStackTaskToTop(reason);
//build模式
//obtainStarter()返回ActivityStarter
//最后执行的ActivityStarter..execute()
mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason)
.setOutActivity(tmpOutRecord)
.setCallingUid(0)
.setActivityInfo(aInfo)
.execute();
mLastHomeActivityStartRecord = tmpOutRecord[0];
//inResumeTopActivity=false
if (mSupervisor.inResumeTopActivity) {
mSupervisor.scheduleResumeTopActivities();
}
}
obtainStarter
//关注点是返回ActivityStarter
ActivityStarter obtainStarter(Intent intent, String reason) {
return mFactory.obtain().setIntent(intent).setReason(reason);
}
这里返回ActivityStarter,跟Launcher启动Activity的一样流程。
ActivityStarter.java
frameworks\base\services\core\java\com\android\server\am\ActivityStarter.java
这里的mRequest.mayWait为false,也就是走else
int execute() {
try {
//如果有调用.setMayWait(userId),这里会设置过true
if (mRequest.mayWait) {
return startActivityMayWait(mRequest.caller, mRequest.callingUid,
mRequest.callingPackage, mRequest.intent, mRequest.resolvedType,
mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
mRequest.inTask, mRequest.reason,
mRequest.allowPendingRemoteAnimationRegistryLookup);
} else {
return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
mRequest.outActivity, mRequest.inTask, mRequest.reason,
mRequest.allowPendingRemoteAnimationRegistryLookup);
}
} finally {
onExecutionComplete();
}
}
这里不继续跟了,就是startActivity的启动过程。后续会单独分析Activity的启动。
参考文章
历史上的今天
暂无评论...
随机推荐
启动startService()分析(2)
接上一篇《Android 6.0 启动startService()源码分析(1)》,依旧分析startService()启动过程。由于篇幅过长,分开记录,便于阅读。10.4 ActivityManagerProxy.attachApplication在上一篇中的代码中 【获取的又是Activi...
Android机型适配相关摘抄
前言由于Android分辨多样,在做适配时总感觉困惑,怎么配置?(哈哈哈,之前项目一直都是一个分辨率的,不用做兼容,不同客户需求不一样)6个主流分辨率:800480、480320、1280720、854480、960540、19201080因此,摘抄如下内容。正文屏幕相关概念屏幕尺寸、...
尼采:孩子和婚姻
兄弟,我单独问你一个问题,这个问题就如探测之铅坠,我可据此了解你的灵魂。你年轻,渴望孩子与婚姻,但我问你,你有资格渴求孩子吗?你是胜利者吗?你战胜自己了吗?你能控制感情吗?你可以主宰你的美德吗?你的渴望是动物般的需要呢,还是孤独或内心冲突的表现?我希望你拥有胜利和自由后再渴望孩子,你应当为自己的...
西贝:路人
不知为何,明明想和你说话。却骗你说,风雨正好,该去写点诗句。 不必嘲讽我,你笑出声来,我也当是天籁。 不必怀有敌意,你所有心计,我都当是你对我的心意。 我的宿命分两段,未遇见你时,和遇见你以后。你治好我的忧郁,而后赐我悲伤。 忧郁和悲...
sendBroadcast静态广播源码分析
前言本次分析一下Android P开机后发送静态广播源码分析,记录一下,方便自己查阅。部分流程跟前面的源码分析《startActivity源码分析》和《startService源码分析》都比较类似,所以重复的步骤就省略。PS:启动startActivity的比较复杂,流程多,但搞懂了这个,...
Android startActivity去掉自带的动画效果
Android中startActivity系统自带动画效果,如果需要取消动效,可以考虑如下两种方式。使用overridePendingTransition在启动Activity后添加此代码Intent intent = new Intent(mContext, MainActivity.cl...