Android 7.0 SystemUI 之启动和状态栏和导航栏简介
一、SystemUI 是什么
首先SystemUI 是一个系统应用,apk路径位于/system/priv-app
源码路径位于:/framework/base/packages/SystemUI
它负责的功能如下:
- 状态栏信息的展示:比如电量信息,时间,wifi状态等
- 通知栏消息
- 壁纸管理
- 截图功能
- 近期任务栏显示,比如长按home键显示最近使用的app
- 录制屏幕功能
- 截图服务
以下是7.0 SystemUI 的代码截图
二、SystemUI 的启动
SystemUI 是在SystemServer里的AMS实例的systemReady方法里调用startSystemUi方法启动
SystemServer路径:/base/services/java/com/android/server/SystemServer.java
mActivityManagerService.systemReady(new Runnable() {
......
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);
}
......
在这个方法里启动一个SystemUIService服务.
public class SystemUIService extends Service {
@Override
public void onCreate() {
super.onCreate();
((SystemUIApplication) getApplication()).startServicesIfNeeded();
}
......
在onCreate方法中会调用SystemUIApplication的startServicesIfNeeded方法,这个方法会调用 startServicesIfNeeded(SERVICES)方法启动一系列服务(并不是真正的服务,都继承自SystemUI),可以这么说SystemUI就是一个容器,里面装有负责不同功能的模块。
public class SystemUIApplication extends Application {
......
private final Class<?>[] SERVICES = new Class[] {
com.android.systemui.tuner.TunerService.class,
com.android.systemui.keyguard.KeyguardViewMediator.class,
com.android.systemui.recents.Recents.class,
com.android.systemui.volume.VolumeUI.class,
Divider.class,
com.android.systemui.statusbar.SystemBars.class,
com.android.systemui.usb.StorageNotification.class,
com.android.systemui.power.PowerUI.class,
com.android.systemui.media.RingtonePlayer.class,
com.android.systemui.keyboard.KeyboardUI.class,
com.android.systemui.tv.pip.PipUI.class,
com.android.systemui.shortcut.ShortcutKeyDispatcher.class
};
public void startServicesIfNeeded() {
startServicesIfNeeded(SERVICES);
}
......
startServicesIfNeeded方法会遍历services这个数组,依次调用service的start方法启动服务
private void startServicesIfNeeded(Class<?>[] services) {
//如果已经启动了就返回
if (mServicesStarted) {
return;
}
//如果没启动完成完成
if (!mBootCompleted) {
if ("1".equals(SystemProperties.get("sys.boot_completed"))) {
mBootCompleted = true;
if (DEBUG) Log.v(TAG, "BOOT_COMPLETED was already sent");
}
}
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].start();
//如果启动完成了
if (mBootCompleted) {
mServices[i].onBootCompleted();
}
}
mServicesStarted = true;
}
这里以com.android.systemui.statusbar.SystemBars.class为例,讲解一下
三、状态栏和导航栏 的启动
SystemBars的start方法会创建一个ServiceMonit