本文基于Android 7.0,记录SystemUI学习过程,如有错误之处 请谅解。
涉及到的代码
frameworks/base/services/java/com/android/server/SystemServer.java
frameworks/base/core/java/android/app/ContextImpl.java
frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
frameworks/base/core/java/android/app/ActivityThread.java
frameworks/base/packages/SystemUI/
SystemUI是系统app,源码位于framework/base/package/SystemUI。
SystemUI启动是从frameworks/base/services/java/com/android/server/SystemServer.java main()开始的。
/**
* The main entry point from zygote.
*/
public static void main(String[] args) {
new SystemServer().run();
}
进入到run()中
private void run() {
...
// Start services.
try {
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices");
startBootstrapServices();
startCoreServices();
startOtherServices();
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
...
}
所有的系统服务都是在这里启动的,其中在startBootstrapServices()中启动了ActivityManagerService、PowerManagerService、PackageManagerService等一系列核心服务,SystemUI是在startOtherServices()中。
/**
* Starts a miscellaneous grab bag of stuff that has yet to be refactored
* and organized.
*/
private void startOtherServices(){
...
WindowManagerService wm = null;
...
try {
...
wm = WindowManagerService.main(context, inputManager,
mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
!mFirstBoot, mOnlyCore);
ServiceManager.addService(Context.WINDOW_SERVICE, wm);
...
} catch (RuntimeException e) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting core service", e);
}
...
StatusBarManagerService statusBar = null;
INotificationManager notification = null;
...
if (mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
...
if (!disableSystemUI) {
traceBeginAndSlog("StartStatusBarManagerService");
try {
statusBar = new StatusBarManagerService(context, wm);
ServiceManager.addService(Context.STATUS_BAR_SERVICE, statusBar);
} catch (Throwable e) {
reportWtf("starting StatusBarManagerService", e);
}
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
...
mSystemServiceManager.startService(NotificationManagerService.class);
notification = INotificationManager.Stub.asInterface(
ServiceManager.getService(Context.NOTIFICATION_SERVICE));
...
}
...
// We now tell the activity manager it is okay to run third party
// code. It will call back into us once it has gotten to the state
// where third party code can really run (but before it has actually
// started launching the initial applications), for us to complete our
// initialization.
mActivityManagerService.systemReady(new Runnable() {
@Override
public void run() {
...
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartSystemUI");
try {
startSystemUi(context);
} catch (Throwable e) {
reportWtf("starting System UI", e);
}
...
}
});
}
startOtherServices()还启动了大名鼎鼎的WindowManagerService。然后启动StatusBarManagerService,该服务是用来和SystemUI交互的。所有的系统服务启动完成之后,ams会调用systemReady去真正开始启动SystemUI。
frameworks/base/services/java/com/android/server/SystemServer.java
static final void startSystemUi(Context context) {
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);
}
可以看到这里是通过context的startServiceAsUser去启动SystemUIService。该方法的真正实现是在ContextImpl.java
frameworks/base/core/java/android/app/ContextImpl.java
@Override
public ComponentName startServiceAsUser(Intent service, UserHandle user) {
return startServiceCommon(service, user);
}
private ComponentName startServiceCommon(Intent service, UserHandle user) {
try {
validateServiceIntent(service);
service.prepareToLeaveProcess(this);
ComponentName cn = ActivityManagerNative.getDefault().startService(
mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
getContentResolver()), getOpPackageName(), user.getIdentifier());
if (cn != null) {
if (cn.getPackageName().equals("!")) {
throw new SecurityException(