Android系统揭秘(四)-Launcher的启动

==

上文Android系统启动概述分析了系统的启动,而启动的最后一步则是启动Launcher

什么是Launcher

img
如果你不知道什么Launcher的话,看到上面的页面应该就知道了,Launcher其实就是桌面。
桌面上的图标则是启动器,我们可以通过这些图标启动对应的应用程序。

Launcher的启动

因为各版本差别比较大,所以分开几个版本分析,不想看源码的同学可以直接滑文末看总结

Android 8,9

先过下整体时序图: img
上文中我们知道Zygote进程启动了SystemServer进程, 而启动 Launcher的入口为AMS的systemReady方法, 在SystemServer的startOtherServices方法中被调用

如下所示:

frameworks/base/services/java/com/android/server/SystemServer.java

public final class SystemServer {
private void run() {

// Start services.
try {
t.traceBegin(“StartServices”);
startBootstrapServices(t);
startCoreServices(t);
startOtherServices(t);
} catch (Throwable ex) {
Slog.e(“System”, “******************************");
Slog.e(“System”, "
Failure starting system services”, ex);
throw ex;
} finally {
t.traceEnd(); // StartServices
}

}

private void startOtherServices(@NonNull TimingsTraceAndSlog t) {

mActivityManagerService.systemReady(() -> {
Slog.i(TAG, “Making services ready”);
t.traceBegin(“StartActivityManagerReadyPhase”);
mSystemServiceManager.startBootPhase(t, SystemService.PHASE_ACTIVITY_MANAGER_READY);

}

}
}


看下systemReady的实现

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {

mStackSupervisor.resumeFocusedStackTopActivityLocked();
mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
traceLog.traceEnd(); // ActivityManagerStartApps
traceLog.traceEnd(); // PhaseActivityManagerReady
}

可知下面交给了ActivityStackSupervisor


frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

boolean resumeFocusedStackTopActivityLocked(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {

if (!readyToResume()) {
return false;
}

if (targetStack != null && isFocusedStack(targetStack)) {
return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}


return false;
}

后面则是调用ActivityStack的resumeTopActivityUncheckedLocked方法


frameworks/base/services/core/java/com/android/server/am/ActivityStack.java

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;
result = resumeTopActivityInnerLocked(prev, options);
} finally {
mStackSupervisor.inResumeTopActivity = false;
}

return result;
}

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {

return isOnHomeDisplay() &&
mStackSupervisor.resumeHomeStackTask(prev, “prevFinished”);

}

ActivityStack最终又调用了ActivityStackSupervisor的resumeHomeStackTask方法

frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

boolean resumeHomeStackTask(ActivityRecord prev, String reason) {

mHomeStack.moveHomeStackTaskToTop();
ActivityRecord r = getHomeActivity();
final String myReason = reason + " resumeHomeStackTask";

// Only resume home activity if isn’t finishing.
if (r != null && !r.finishing) {
moveFocusableActivityStackToFrontLocked(r, myReason);
return resumeFocusedStackTopActivityLocked(mHomeStack, prev, null);
}
return mService.startHomeActivityLocked(mCurrentUser, myReason);
}

最后回到AMS,调用AMS的startHomeActivityLocked方法

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

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.instr == null) {
intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
// For ANR debugging to verify if the user activity is the one that actually
// launched.
final String myReason = reason + “:” + userId + “:” + resolvedUserId;
mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);
}
} else {
Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
}

return true;
}

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

这里启动了一个Intent,可以通过源码看到Launcher的清单配置

packages/apps/Launcher3/AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>









最终使用ActivityStarter启动Launcher,后面的流程可参考Activity的启动

frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java

void startHomeActivityLocked(Intent intent, ActivityInfo aInfo, String reason) {
mSupervisor.moveHomeStackTaskToTop(reason);
mLastHomeActivityStartResult = 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/, mLastHomeActivityStartRecord /outActivity/,
null /inTask/, "startHomeActivity: " + reason);


}

小结

  • SystemServer中使用AMS启动Launcher
  • AMS调用 ActivityStackSupervisor的resumeFocusedStackTopActivityLocked方法
  • 经历了ActivityStackSupervisor -> ActivityStack -> ActivityStackSupervisor ->AMS 的流程,期间处理了一些堆栈相关的工作,最终又回到了AMS
  • AMS调用 ActivityStarter启动Launcher Activity

建议看完源码,回头看下时序图,会比较清晰

Android 10

时序图:
img

与安卓8一样从AMS启动,不同的是安卓10交给了一个ActivityTaskManagerInternal类型的服务mAtmInternal
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

@VisibleForTesting
public ActivityTaskManagerInternal mAtmInternal;
public ActivityManagerService(Context systemContext, ActivityTaskManagerService atm) {

mAtmInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
}
public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {

t.traceBegin(“resumeTopActivities”);
mAtmInternal.resumeTopActivities(false /* scheduleIdle */);
t.traceEnd();

}

我们看下mAtmInternal哪来的,LocalServices类里面是一个类与对象的键值对, 而ActivityTaskManagerInternal是一个抽象类,我们找到它的唯一继承类ActivityTaskManagerService.LocalService

frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java

public class ActivityTaskManagerService extends IActivityTaskManager.Stub {

RootActivityContainer mRootActivityContainer;
final class LocalService extends ActivityTaskManagerInternal {
@Override
public void resumeTopActivities(boolean scheduleIdle) {
synchronized (mGlobalLock) {
mRootActivityContainer.resumeFocusedStacksTopActivities();

}
}
}
}

这里调用了RootActivityContainer的resumeFocusedStacksTopActivities方法

frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java

boolean resumeFocusedStacksTopActivities() {
return resumeFocusedStacksTopActivities(null, null, null);
}
boolean resumeFocusedStacksTopActivities(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {

for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {

if (!resumedOnDisplay) {

final ActivityStack focusedStack = display.getFocusedStack();
if (focusedStack != null) {
focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
}
}

return result;
}

老环节,接下来又走到了ActivityStack

frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java

boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {

result = resumeTopActivityInnerLocked(prev, options);

}

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {

if (!hasRunningActivity) {
// There are no activities left in the stack, let’s look somewhere else.
return resumeNextFocusableActivityWhenStackIsEmpty(prev, options);
}

}

private boolean resumeNextFocusableActivityWhenStackIsEmpty(ActivityRecord prev,
ActivityOptions options) {

return mRootActivityContainer.resumeHomeActivity(prev, reason, mDisplayId);
}

resumeNextFocusableActivityWhenStackIsEmpty 方法又调用了RootActivityContainer的resumeHomeActivity

frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java

boolean resumeHomeActivity(ActivityRecord prev, String reason, int displayId) {


return startHomeOnDisplay(mCurrentUser, myReason, displayId);
}

boolean startHomeOnDisplay(int userId, String reason, int displayId) {
return startHomeOnDisplay(userId, reason, displayId, false /* allowInstrumenting /,
false /
fromHomeKey */);
}

startHomeOnDisplay里面取到了homeIntent,然后我们看最后一行:

boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting,
boolean fromHomeKey) {

Intent homeIntent = null;
ActivityInfo aInfo = null;
if (displayId == DEFAULT_DISPLAY) {
homeIntent = mService.getHomeIntent();
aInfo = resolveHomeActivity(userId, homeIntent);
} else if (shouldPlaceSecondaryHomeOnDisplay(displayId)) {
Pair<ActivityInfo, Intent> info = resolveSecondaryHomeActivity(userId, displayId);
aInfo = info.first;
homeIntent = info.second;
}

// 启动HomeActivity mService 是ActivityTaskManagerService
mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
displayId);
return true;
}

mService.getActivityStartController()获取到的是ActivityStartController

frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java

private ActivityStartController mActivityStartController;
ActivityStartController getActivityStartController() {
return mActivityStartController;
}

public void initialize(IntentFirewall intentFirewall, PendingIntentController intentController,
Looper looper) {

mActivityStartController = new ActivityStartController(this);

}

最后使用ActivityStartController来启动Launcher

frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java

void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason,
TaskDisplayArea taskDisplayArea) {

mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason)
.setOutActivity(tmpOutRecord)
.setCallingUid(0)
.setActivityInfo(aInfo)
.setActivityOptions(options.toBundle())
.execute();
mLastHomeActivityStartRecord = tmpOutRecord[0];

if (homeStack.mInResumeTopActivity) {
mSupervisor.scheduleResumeTopActivities();
}
}

ActivityStarter obtainStarter(Intent intent, String reason) {
return mFactory.obtain().setIntent(intent).setReason(reason);
}
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(资料价值较高,非无偿)

学习宝典

对我们开发者来说,一定要打好基础,随时准备战斗。不论寒冬是否到来,都要把自己的技术做精做深。虽然目前移动端的招聘量确实变少了,但中高端的职位还是很多的,这说明行业只是变得成熟规范起来了。竞争越激烈,产品质量与留存就变得更加重要,我们进入了技术赋能业务的时代。

不论遇到什么困难,都不应该成为我们放弃的理由!

很多人在刚接触这个行业的时候或者是在遇到瓶颈期的时候,总会遇到一些问题,比如学了一段时间感觉没有方向感,不知道该从那里入手去学习,对此我针对Android程序员,我这边给大家整理了一套学习宝典!包括不限于高级UI、性能优化、移动架构师、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter等全方面的Android进阶实践技术;希望能帮助到大家,也节省大家在网上搜索资料的时间来学习,也可以分享动态给身边好友一起学习!

【Android核心高级技术PDF文档,BAT大厂面试真题解析】

【算法合集】

【延伸Android必备知识点】

【Android部分高级架构视频学习资源】

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!

没有方向感,不知道该从那里入手去学习,对此我针对Android程序员,我这边给大家整理了一套学习宝典!包括不限于高级UI、性能优化、移动架构师、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter等全方面的Android进阶实践技术;希望能帮助到大家,也节省大家在网上搜索资料的时间来学习,也可以分享动态给身边好友一起学习!

【Android核心高级技术PDF文档,BAT大厂面试真题解析】

[外链图片转存中…(img-uX6b03uZ-1711611190468)]

【算法合集】

[外链图片转存中…(img-8q8kaaf6-1711611190468)]

【延伸Android必备知识点】

[外链图片转存中…(img-GJzGow3z-1711611190468)]

【Android部分高级架构视频学习资源】

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!
  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android系统启动过程中,会依次启动各个系统服务,其中也包括Launcher服务。LauncherAndroid系统的桌面显示服务,它负责管理并显示设备的主屏幕和应用程序列表。Launcher服务在Android系统的最后阶段启动,即在主界面启动之前。 当设备完成各个系统服务的启动,并且系统进入正常运行状态时,Launcher服务会被启动系统启动时,先启动底层服务如Zygote进程、SystemServer进程等,然后再启动Android应用进程。Launcher服务作为最基本的应用程序之一,需要在其他应用程序之前加载,以确保用户可以正常使用设备的主屏幕。 Launcher服务的启动主要通过系统服务管理器来实现。系统服务管理器负责管理Android系统的各项服务,并按照事先定义好的优先级顺序启动服务。在启动Launcher服务时,系统服务管理器会调用相应的启动函数,加载Launcher相关的资源和配置文件,并开始监控用户对桌面的操作。 一旦Launcher服务启动成功,就会显示设备的主屏幕,并加载应用程序列表。通过Launcher服务,用户可以查看和管理设备上已安装的应用程序,并快捷地启动它们。同时,Launcher服务还提供了桌面小部件、壁纸等个性化设置,使用户可以自定义设备的外观和功能。 总而言之,Android系统Launcher服务在启动过程的最后阶段启动,它管理和显示设备的主屏幕和应用程序列表,为用户提供方便的桌面操作和个性化设置。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值