本文以Android O(8.0)代码为例。主要介绍从SystemService.java到启动SystemUI的过程,至于SystemUI的其他方面放至其他地方说啦。
/frameworks/base/services/java/com/android/server/SystemServer.java
/frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
/frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUIService.java
系统的启动过程是从 init进程 -> Zygote进程 -> SystemServer进程。
话说init进程是怎么启动的呢?
听说是按下电源键之后,系统上电,从固定地址开始加载固化在ROM的Bootloader代码在RAM中并执行,Bootloader引导程序负责将OS拉起;OS被拉起,并完成一系列初始化和系统的初始化,首先在系统文件中寻找init文件并启动用户空间第一个进程。
0. 从代码中可以清晰的看出只做了一件事,就是调用了SystemService的 run() 方法,下面来看一下run()方法里都是运行了哪些东西。
/**
* The main entry point from zygote.
*/
public static void main(String[] args) {
new SystemServer().run();
}
1. 它将服务的启动分为了这几类:Bootstrap、Core、Other,而我们本文所涉及的SystemUI属于Other这一类,所以就进入了startOtherServices()这个私有方法。
private void run() {
...
// Start services.
try {
traceBeginAndSlog("StartServices");
startBootstrapServices();
startCoreServices();
startOtherServices();
SystemServerInitThreadPool.shutdown();
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} finally {
traceEnd();
}
}
2. 在startOtherServices()这个私有方法中,发现系统启动很非常多非常多的服务,SystemUI只是其中一个,下面是只启动SystemUI的相关代码。
private void startOtherServices() {
mActivityManagerService.systemReady(() -> {
...
traceBeginAndSlog("StartSystemUI");
try {
startSystemUi(context, windowManagerF);
} catch (Throwable e) {
reportWtf("starting System UI", e);
}
traceEnd();
...
}, BOOT_TIMINGS_TRACE_LOG);
}
3. 启动SystemUI最后追到了startSystemUi(context, windowManagerF)这样一个方法,找到这个方法,SystemUI怎么启动的也就真相大白了。
至context.startServiceAsUser(),已经设置了包名类名和启动方式来对SystemUI的服务(SystemUIService)开始启动了。值得注意的是,在这个时候,系统还没有发送“ACTION_BOOT_COMPLETE”广播(开机广播),因为该广播是由AMS中的finishBooting()中来发送的。
static final void startSystemUi(Context context, WindowManagerService windowManager) {
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();
}
4. 每一个应用都会自己有一个默认的Application类,也可以根据自己的特殊需求重写一个,在这里呢,SystemUI的应用它自己重写了一个Application类,是伴随应用终身的,每一个apk的启动,该类是最先被初始化的类。
在SystemUIApplication这个类中,定义了两类的Services。
/**
* The classes of the stuff to start.
*/
private final Class>[] SERVICES = new Class[] {
Dependency.class,
NotificationChannels.class,
CommandQueue.CommandQueueStart.class,
KeyguardViewMediator.class,
Recents.class,
VolumeUI.class,
Divider.class,
SystemBars.class,
StorageNotification.class,
PowerUI.class,
RingtonePlayer.class,
KeyboardUI.class,
PipUI.class,
ShortcutKeyDispatcher.class,
VendorServices.class,
GarbageMonitor.Service.class,
LatencyTester.class,
GlobalActionsComponent.class,
};
/**
* The classes of the stuff to start for each user. This is a subset of the services listed
* above.
*/
private final Class>[] SERVICES_PER_USER = new Class[] {
Dependency.class,
NotificationChannels.class,
Recents.class
};
这些所有的类型,都是SystemUI的子类实现。
5. 这时,Application类的onCreate方法被触发了。
@Override
public void onCreate() {
super.onCreate();
// Set the application theme that is inherited by all services. Note that setting the
// application theme in the manifest does only work for activities. Keep this in sync with
// the theme set there.
setTheme(R.style.systemui_theme);
SystemUIFactory.createFromConfig(this);
if (Process.myUserHandle().equals(UserHandle.SYSTEM)) {
IntentFilter filter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED);
filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (mBootCompleted) return;
if (DEBUG) Log.v(TAG, "BOOT_COMPLETED received");
unregisterReceiver(this);
mBootCompleted = true;
if (mServicesStarted) {
final int N = mServices.length;
for (int i = 0; i < N; i++) {
mServices[i].onBootCompleted();
}
}
}
}, filter);
} else {
// We don't need to startServices for sub-process that is doing some tasks.
// (screenshots, sweetsweetdesserts or tuner ..)
String processName = ActivityThread.currentProcessName();
ApplicationInfo info = getApplicationInfo();
if (processName != null && processName.startsWith(info.processName + ":")) {
return;
}
// For a secondary user, boot-completed will never be called because it has already
// been broadcasted on startup for the primary SystemUI process. Instead, for
// components which require the SystemUI component to be initialized per-user, we
// start those components now for the current non-system user.
startServicesIfNeeded(SERVICES_PER_USER);
}
}
在onCreate方法里,有一个广播接收器,他是接收开机广播的。
6. 执行完毕后,开始执行SystemUIService.java的onCreate()方法了,但是onCreate()中只一句话。
@Override
public void onCreate() {
super.onCreate();
((SystemUIApplication) getApplication()).startServicesIfNeeded();
// For debugging RescueParty
if (Build.IS_DEBUGGABLE && SystemProperties.getBoolean("debug.crash_sysui", false)) {
throw new RuntimeException();
}
}
直接又调回到了SystemUIApplication.java中的startServicesIfNeeded()方法。
public void startServicesIfNeeded() {
startServicesIfNeeded(SERVICES);
}
/**
* Ensures that all the Secondary user SystemUI services are running. If they are already
* running, this is a no-op. This is needed to conditinally start all the services, as we only
* need to have it in the main process.
* This method must only be called from the main thread.
*/
void startSecondaryUserServicesIfNeeded() {
startServicesIfNeeded(SERVICES_PER_USER);
}
private void startServicesIfNeeded(Class>[] services) {
if (mServicesStarted) {
return;
}
if (!mBootCompleted) {
// check to see if maybe it was already completed long before we began
// see ActivityManagerService.finishBooting()
if ("1".equals(SystemProperties.get("sys.boot_completed"))) {
mBootCompleted = true;
if (DEBUG) Log.v(TAG, "BOOT_COMPLETED was already sent");
}
}
Log.v(TAG, "Starting SystemUI services for user " +
Process.myUserHandle().getIdentifier() + ".");
final int N = services.length;
for (int i = 0; i < N; i++) {
Class> cl = services[i];
if (DEBUG) Log.d(TAG, "loading: " + cl);
try {
Object newService = SystemUIFactory.getInstance().createInstance(cl);
mServices[i] = (SystemUI) ((newService == null) ? cl.newInstance() : newService);
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (InstantiationException ex) {
throw new RuntimeException(ex);
}
mServices[i].mContext = this;
mServices[i].mComponents = mComponents;
if (DEBUG) Log.d(TAG, "running: " + mServices[i]);
mServices[i].start();
if (mBootCompleted) {
mServices[i].onBootCompleted();
}
}
Dependency.get(PluginManager.class).addPluginListener(
new PluginListener() {
private ArraySet mOverlays;
@Override
public void onPluginConnected(OverlayPlugin plugin, Context pluginContext) {
StatusBar statusBar = getComponent(StatusBar.class);
if (statusBar != null) {
plugin.setup(statusBar.getStatusBarWindow(),
statusBar.getNavigationBarView());
}
// Lazy init.
if (mOverlays == null) mOverlays = new ArraySet<>();
if (plugin.holdStatusBarOpen()) {
mOverlays.add(plugin);
Dependency.get(StatusBarWindowManager.class).setStateListener(b ->
mOverlays.forEach(o -> o.setCollapseDesired(b)));
Dependency.get(StatusBarWindowManager.class).setForcePluginOpen(
mOverlays.size() != 0);
}
}
@Override
public void onPluginDisconnected(OverlayPlugin plugin) {
mOverlays.remove(plugin);
Dependency.get(StatusBarWindowManager.class).setForcePluginOpen(
mOverlays.size() != 0);
}
}, OverlayPlugin.class, true /* Allow multiple plugins */);
mServicesStarted = true;
}
这里是拿到每个和 SystemUI 相关的类的反射,存到了 service[] 里,然后再通过反射将其转化为具体类的对象,存到了mService[i]数组里,最后对象调 start() 方法启动相关类的服务,启动完成后,回调 onBootCompleted( ) 方法。
因为mService[i] 里的值不同,调用的 start() 方法也不尽相同。
史上最详细的Android系统SystemUI 启动过程详细解析
开机SystemServer到ActivityManagerService启动过程分析
SystemUI启动流程及主体布局介绍
https://blog.csdn.net/qq_28852011/article/details/79449631