一、前提提要
Launcher即桌面程序是在系统服务等启动后打开的第一个应用程序进程,主要管理手机内部的各个用户App的展示与打开等功能,在开启Launcher的过程中SystemUI 如导航栏等布局也相继加载到屏幕中。
Launcher的启动在各种系统服务初始化完成后进行的,即SystemServer的startOtherService()方法最后
二、启动流程
1、SystemServer.run()
//com.android.server.SystemServer
private void run() {
try{
......
//1、创建系统Context
createSystemContext();
......
}catch(..){..}
......
try{
......
//2、启动其他服务
startOtherServices();
......
}catch(..){..}
//......
}
系统服务如:AMS\ATMS、PMS、WMS等都是在SystemServer的run()方法中启动初始化,关于系统服务的启动不做过多介绍,这里主要有是创建了系统Context为后续启动做准备,然后进入到startOtherServices方法中
2、startOhterServices()
//com.android.server.SystemServer
private void startOtherServices() {
final Context context = mSystemContext;
......
//wms、ims等各种服务初始化
......
//通过AMS做启动前的准备
mActivityManagerService.systemReady(() -> {
......
try {
//2、启动系统UI
startSystemUi(context, windowManagerF);
} catch (Throwable e) {
reportWtf("starting System UI", e);
}
......
},BOOT_TIMINGS_TRACE_LOG);
}
在startOtherServices方法中先是完成必要的系统服务后,通过AMS开始对Launcher的启动进行准备工作,调用AMS的systemReady方法传入了一个Callback,并且在Callback中又对系统UI进行启动
3、启动SystemUI
//com.android.server.SystemServer
private static void startSystemUi(Context context, WindowManagerService windowManager) {
//启动系统UI Service
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.android.systemui",
"com.android.systemui.SystemUIService"));
intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
//Slog.d(TAG, "Starting service: " + intent);
context.startServiceAsUser(intent, UserHandle.SYSTEM);
windowManager.onSystemUiStarted();
}
通过启动Service的方式初始化UI
//com.android.systemui.SystemUIService
public class SystemUIService extends Service {
@Override
public void onCreate() {
super.onCreate();
//执行SystemUIApplication中的创建方法
((SystemUIApplication) getApplication()).startServicesIfNeeded();
......
}
......
}
在Service的onCreate()方法中又调用了当前Application的startServicesIfNeeded方法继续初始化
在前面的createSystemContext()方法中创建了Context的同时也创建的Application对象,Application的具体实例类型是通过解析对应的AndroidManifest.xml获取,此处创建的Application所解析的xml在 /frameworks/base/packages/SystemUI 包下
//frameworks/base/packages/SystemUI/AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
package="com.android.systemui"
android:sharedUserId="android.uid.systemui"
coreApp="true">
......
<application
//Application类
android:name=".SystemUIApplication"
android:persistent="true"
android:allowClearUserData="false"
android:allowBackup="false"
.....
</application>
</manifest>
SystemUIApplication中继续执行
//com.android.systemui.SystemUIApplication
public void startServicesIfNeeded() {
//获取需要初始化系统UI的名字
String[] names = getResources().getStringArray(R.array.config_systemUIServiceComponents);
startServicesIfNeeded(names);
}
private void startServicesIfNeeded(String[] services) {
if (mServicesStarted) {
return;
}
//SystemUI集合,系统UI都继承自SystemUI
mServices = new SystemUI[services.length];
......
final int N = services.length;
for (int i = 0; i < N; i++) {
String clsName = services[i];
......
Class cls;
try {
//通过反射实例化各个系统UI
cls = Class.forName(clsName);
Object o = cls.newInstance();
if (o instanceof SystemUI.Injector) {
o = ((SystemUI.Injector) o).apply(this);
}
mServices[i] = (SystemUI) o;
} ......
mServices[i].mContext = this;
mServices[i].mComponents = mComponents;
if (DEBUG) Log.d(TAG, "running: " + mServices[i]);
//初始化系统UI (4-1)
mServices[i].start();
......
if (mBootCompleted) {
mServices[i].onBootCompleted();
}
}
.......
}
从config.xml获取需要初始化的各个SystemUI类名,然后创建SystemUI数组并遍历集合通过反射的方式创建实例,最后调用SystemUI.start()方法对每个SystemUI初始化和渲染
config_systemUIServiceComponents定义在在/frameworks/base/packages/SystemUI/res/values/config.xml 文件下,其中包括了 如 顶部状态栏、通知、键盘等一些列UI
<!-- SystemUI Services: The classes of the stuff to start. -->
<string-array name="config_systemUIServiceComponents" translatable="false">
<item>com.android.systemui.Dependency</item>
<item>com.android.systemui.util.NotificationChannels</item>
<item>com.android.systemui.statusbar.CommandQueue$CommandQueueStart</item>
<item>com.android.systemui.keyguard.KeyguardViewMediator</item>
<item>com.android.systemui.recents.Recents</item>
<item>com.android.systemui.volume.VolumeUI</item>
<item>com.android.systemui.stackdivider.Divider</item>
<item>com.android.systemui.SystemBars</item>
<item>com.android.systemui.usb.StorageNotification</item>
<item>com.android.systemui.power.PowerUI</item>
<item>com.android.systemui.media.RingtonePlayer</item>
<item>com.android.systemui.keyboard.KeyboardUI</item>
<item>com.android.systemui.pip.PipUI</item>
<item>com.android.systemui.shortcut.ShortcutKeyDispatcher</item>
<item>@string/config_systemUIVendorServiceComponent</item>
<item>com.android.systemui.util.leak.GarbageMonitor$Service</item>
<item>com.android.systemui.LatencyTester</item>
<item>com.android.systemui.globalactions.GlobalActionsComponent</item>
<item>com.android.systemui.ScreenDecorations</item>
<item>com.android.systemui.fingerprint.FingerprintDialogImpl</item>
<item>com.android.systemui.SliceBroadcastRelayHandler</item>
</string-array>
以SystemBars为例:
//继承自SystemUI
public class SystemBars extends SystemUI {
......
//执行的start()方法
@Override
public void start() {
if (DEBUG) Log.d(TAG, "start");
//创建StatusBar
createStatusBarFromConfig();
}
......
private void createStatusBarFromConfig() {
if (DEBUG) Log.d(TAG, "createStatusBarFromConfig");
//获取StatusBar类名
//com.android.systemui.statusbar.phone.StatusBar
final String clsName = mContext.getString(R.string.config_statusBarComponent);
if (clsName == null || clsName.length() == 0) {
throw andLog("No status bar component configured", null);
}
Class<?> cls = null;
try {
cls = mContext.getClassLoader().loadClass(clsName);
} catch (Throwable t) {
throw andLog("Error loading status bar component: " + clsName, t);
}
try {
//通过反射创建StatusBar对象
mStatusBar = (SystemUI) cls.newInstance();
} catch (Throwable t) {
throw andLog("Error creating status bar component: " + clsName, t);
}
mStatusBar.mContext = mContext;
mStatusBar.mComponents = mComponents;
if (mStatusBar instanceof StatusBar) {
SystemUIFactory.getInstance().getRootComponent()
.getStatusBarInjector()
.createStatusBar((StatusBar) mStatusBar);
}
//StatusBar也是继承SystemUI继续执行start方法
mStatusBar.start();
if (DEBUG) Log.d(TAG, "started " + mStatusBar.getClass().getSimpleName());
}
......
}
SystemBar的start()中创建了StatusBar对象,StatusBar也是继承自SystemUI,再次执行start()方法
//com.android.systemui.statusbar.phone.StatusBar
//继承SystemUI
public class StatusBar extends SystemUI implements ...{
......
@Override
public void start() {
......
//获取WMS
mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
......
mWindowManagerService = WindowManagerGlobal.getWindowManagerService();
......
//创建并将view添加到屏幕
createAndAddWindows(result);
......
}
......
public void createAndAddWindows(@Nullable RegisterStatusBarResult result) {
//创建StatusView
makeStatusBarView(result);
mStatusBarWindowController = Dependency.get(StatusBarWindowController.class);
//添加到Window 涉及到WMS绘制
mStatusBarWindowController.add(mStatusBarWindow, getStatusBarHeight());
}
}
可以看到StatusBar中实际创建了View,并通过WMS绘制到屏幕中
4、启动Launcher
继续回到SystemServer代码
//com.android.server.SystemServer
private void startOtherServices() {
......
//通过AMS做启动前的准备
mActivityManagerService.systemReady(() -> {
......
try {
//2、启动系统UI
startSystemUi(context, windowManagerF);
} catch (Throwable e) {
reportWtf("starting System UI", e);
}
......
},BOOT_TIMINGS_TRACE_LOG);
}
进入到AMS.systemReady()方法
//com.android.server.am.ActivityManagerService.java
public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
synchronized(this) {
if (mSystemReady) {
// 如果初始化过一次 那就直接执行callback
if (goingCallback != null) {
goingCallback.run();
}
return;
}
mLocalDeviceIdleController
= LocalServices.getService(DeviceIdleController.LocalService.class);
//准备完成配置信息
mActivityTaskManager.onSystemReady();
mUserController.onSystemReady();
mAppOpsService.systemReady();
mSystemReady = true;
}
......
//执行callback 初始化系统UI等操作
if (goingCallback != null) goingCallback.run();
......
synchronized (this) {
......
//启动Launcher
mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
......
}
}
在内部做了防止多次初始化启动的操作,配置完各项信息调用ActivityTaskManagerInternal的startHomeOnAllDisplays启动Launcher
这里简单了解一下mAtmInternal的创建过程
1、mAtmInternal是ActivityTaskManagerInternal类型,管理AtivityTaskManager
功能的接口。它的获取是在ActivityManagerService构造方法中
public ActivityManagerService(Context systemContext,
ActivityTaskManagerService atm) {
......
//通过ATMI.class获取具体实现类
mAtmInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
......
}
LocalServices内部维护一个Map,主要用来存取本地的一些接口服务此处获取ActivityTaskManagerInternal的实现类
2、ActivityTaskManagerInternal是一个接口具体实现类是ActivityTaskManagerService
内部的LocalService
public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
......
final class LocalService extends ActivityTaskManagerInternal {
......
}
......
}
3、LocalService的创建是在ATMS的构造函数中,而添加到LocalServices是在ATMS
服务启动的时候
public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
......
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
public ActivityTaskManagerService(Context context) {
......
mInternal = new LocalService();
......
}
......
//ATMS启动
private void start() {
//添加到LocalServices,key为ATMI.class
LocalServices.addService(ActivityTaskManagerInternal.class, mInternal);
}
}
ATMS的启动则是在SystemServer中进行的,这里就不多做赘述
继续回到mAtmInternal.startHomeOnAllDisplays方法
final class LocalService extends ActivityTaskManagerInternal {
......
@Override
public boolean startHomeOnAllDisplays(int userId, String reason) {
synchronized (mGlobalLock) {
//继续执行RootWindowContainer的方法
return mRootWindowContainer.startHomeOnAllDisplays(userId, reason);
}
}
......
}
RootWindowContainer.startHomeOnAllDisplays
class RootActivityContainer extends ConfigurationContainer
implements DisplayManager.DisplayListener {
......
boolean startHomeOnAllDisplays(int userId, String reason) {
boolean homeStarted = false;
for (int i = mActivityDisplays.size() - 1; i >= 0; i--) {
final int displayId = mActivityDisplays.get(i).mDisplayId;
//1、获取并继续调用启动方法
homeStarted |= startHomeOnDisplay(userId, reason, displayId);
}
return homeStarted;
}
......
boolean startHomeOnDisplay(int userId, String reason, int displayId) {
//2、
return startHomeOnDisplay(userId, reason, displayId, false /* allowInstrumenting */,
false /* fromHomeKey */);
}
boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting,
boolean fromHomeKey) {
// Fallback to top focused display or default display if the displayId is invalid.
if (displayId == INVALID_DISPLAY) {
final ActivityStack stack = getTopDisplayFocusedStack();
displayId = stack != null ? stack.getDisplayId() : DEFAULT_DISPLAY;
}
final DisplayContent display = getDisplayContent(displayId);
boolean result = false;
for (int tcNdx = display.getTaskDisplayAreaCount() - 1; tcNdx >= 0; --tcNdx) {
final TaskDisplayArea taskDisplayArea = display.getTaskDisplayAreaAt(tcNdx);
result |= startHomeOnTaskDisplayArea(userId, reason, taskDisplayArea,
allowInstrumenting, fromHomeKey);
}
return result;
}
boolean startHomeOnTaskDisplayArea(int userId, String reason, int displayId, boolean allowInstrumenting,
boolean fromHomeKey) {
......
//Launcher的Intent
Intent homeIntent = null;
ActivityInfo aInfo = null;
//3、获取Launcher的Activity信息
if (taskDisplayArea == getDefaultTaskDisplayArea()) {
homeIntent = mService.getHomeIntent();
aInfo = resolveHomeActivity(userId, homeIntent);
} else if (shouldPlaceSecondaryHomeOnDisplayArea(taskDisplayArea)) {
Pair<ActivityInfo, Intent> info = resolveSecondaryHomeActivity(userId, taskDisplayArea);
aInfo = info.first;
homeIntent = info.second;
}
......
//检测是否允许启动
//内部有对系统运行模式和TopAction以及分屏的判断
if (!canStartHomeOnDisplayArea(aInfo, displayId, allowInstrumenting)) {
return false;
}
//更新Launcher的启动信息
homeIntent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
homeIntent.setFlags(homeIntent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
// Updates the extra information of the intent.
if (fromHomeKey) {
homeIntent.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, true);
}
// Update the reason for ANR debugging to verify if the user activity is the one that
// actually launched.
final String myReason = reason + ":" + userId + ":" + UserHandle.getUserId(
aInfo.applicationInfo.uid) + ":" + displayId;
//4、启动Launcher Activity
mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
displayId);
return true;
}
}
最后通过ATMS获取ActivityStartController对象,并调用startHomeActivity启动了Launcher。
后续启动流程与点击App应用冷启动过程类似,等整理完成后再出下一篇博客
三、最后
本文通过自己对Android 10版本源码的理解整理发布,其中很多细节不够详细还需要进一步理解,如果出现错误欢迎指正,如果小伙伴有更好的流程解析欢迎一起探讨
2160

被折叠的 条评论
为什么被折叠?



