一.SystemUI概述
SystemUI 是一个系统应用,apk路径位于/system/priv-app
源码路径位于:/framework/base/packages/SystemUI
主要负责功能:
- StatusBar:状态栏
- NavigationBar:导航栏(返回、home、近期任务)
- Notification Panel:通知栏以及快捷设置面板
- 壁纸管理
- 截图功能
- Recents:近期任务(android9使用的是launcher3里面的近期任务,但是SystemUI9也保留了相关代码,可在systemUi中设置使用哪个)
- 录制屏幕功能
- 截图服务
- VolumeBar:音量控制
- Keyguard 锁屏界面
- RingtonePlayer 铃声播放器界面
- PipUI 画中画界面
- RingtonePlayer 铃声播放器界面
。。。。。
二.SystemUI 的启动
系统开机大致流程:
uboot引导os启动 > 加载kernel > init进程,fork出zygote进程 > zygote启动SystemServer;
SystemServer负责系统各种核心服务的启动以及初始化和加载一些应用。
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 {
traceBeginAndSlog("StartServices");
startBootstrapServices(); //引导服务
startCoreServices(); //核心服务
startOtherServices(); //其他
SystemServerInitThreadPool.shutdown();
}
...
}
三个start方法从命名可用看出分别用于启动引导服务、核心服务和其他服务。startBootstrapServices():
private void startBootstrapServices() {
...
Installer installer = mSystemServiceManager.startService(Installer.class);
mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class);
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
mSystemServiceManager.startService(LightsService.class);
mSystemServiceManager.startService(new OverlayManagerService(mSystemContext, installer));
...
}
可以看到AMS,PMS,LightsService等服务是在这里开启的。
SystemUI的启动位于startOtherServices():
private void startOtherServices() {
...
traceBeginAndSlog("StartSystemUI");
try {
startSystemUi(context, windowManagerF);
} catch (Throwable e) {
reportWtf("starting System UI", e);
}
...
}
这个方法代码非常多,只列出了关键的地方,接着看startSystemUi方法:
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();
}
创建Intent,通过组件名com.android.systemui.SystemUIService启动了SystemUIService服务。至此终于走到了SystemUI项目中。
三.SystemUI的加载
com.android.systemui.SystemUIService.java
public class SystemUIService extends Service {
@Override
public void onCreate() {
super.onCreate();
((SystemUIApplication) getApplication()).startServicesIfNeeded();
...
}
}
SystemUIService继承了Service,onCreate调用了SystemUIApplication的startServicesIfNeeded方法:
public class SystemUIApplication extends Application...{
public void startServicesIfNeeded() {
String[] names = getResources().getStringArray(R.array.config_systemUIServiceComponents);
startServicesIfNeeded(names);
}
}
config_systemUIServiceComponents数组包含了各个功能模块的全类名,如下
<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>
可以看到对应上1中提到的各个功能模块。接下来是真正的加载方法,
startServicesIfNeeded(String[] services)
private void startServicesIfNeeded(String[] services) {
if (mServicesStarted) {
return;
}
mServices = new SystemUI[services.length];
......
final int N = services.length;
for (int i = 0; i < N; i++) {
String clsName = services[i];
if (DEBUG) Log.d(TAG, "loading: " + clsName);
log.traceBegin("StartServices" + clsName);
long ti = System.currentTimeMillis();
Class cls;
try {
cls = Class.forName(clsName);
mServices[i] = (SystemUI) cls.newInstance();
} catch(ClassNotFoundException ex){
throw new RuntimeException(ex);
} 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();
log.traceEnd();
// Warn if initialization of component takes too long
ti = System.currentTimeMillis() - ti;
if (ti > 1000) {
Log.w(TAG, "Initialization of " + cls.getName() + " took " + ti + " ms");
}
if (mBootCompleted) {
mServices[i].onBootCompleted();
}
}
......
}
首先新建了SystemUI数组(mServices),再遍历传入的services数组通过反射获取SystemUI对象赋值给mServices数组,最后通过mServices[i].start()加载各个模块。注意这里的mServices[i].start并不是常说的启动服务,以NotificationChannels为例:
NotificationChannels 继承了SystemUI :
public abstract class SystemUI implements SysUiServiceProvider {
public Context mContext;
public Map<Class<?>, Object> mComponents;
public abstract void start();
....
}
public class NotificationChannels extends SystemUI{
@Override
public void start() {
createAll(mContext);
}
}
也就是说各个模块都继承了SystemUI,各自重写了start方法,mServices[i].start()调用了各自模块的start方法,完成加载。