一、SystemUI的介绍
SystemUI是Android操作系统中的一个关键系统级应用,负责管理和提供用户界面的核心元素,
主要包括:StatusBar(状态栏)、NavigationBar(导航栏)与Notification Panel(通知栏),以及Notification Panel(通知面板)等,另外在Android8.0代码中,Keyguard(锁屏)模块已经从外部被合并到SystemUI源码目录下。
关于Android13的架构层级如下:
1、状态栏:StatusBar是Android SystemUI的核心组件之一,位于屏幕顶部。它显示了通知图标、系统图标(如电池、信号强度、时间等)以及其他与系统状态相关的信息。
2、导航栏:NavigationBar是位于屏幕底部的导航界面,提供了返回、主页和最近任务等导航操作的按钮。它使用户能够浏览应用程序和系统功能,如切换应用、返回主屏幕等。
3、通知栏:Notification Shade是一个可下拉的面板,用户可以从任何屏幕位置向下滑动以展开它。它显示了来自各个应用程序的通知,并提供一些快速设置选项,如Wi-Fi、蓝牙、飞行模式等。
4、快捷控制:Quick Settings是通知面板中的一部分,提供了一组常用的系统设置选项,用户可以通过快速切换按钮打开或关闭这些选项,例如调整屏幕亮度、打开/关闭无线网络等。
以下是Android SystemUI的主要功能的介绍:
二、启动流程
SystemUI 的启动本质是 SystemServer 进程初始化系统服务的一部分,其核心流程可分为以下阶段(以 Android 13 为例):
1、SystemServer 启动:Android 系统启动时,init 进程启动 system_server 进程(SystemServer.java)。
2、加载系统服务配置:读取 /system/etc/systemui/config.xml 等配置文件,确定需要启动的 SystemUI 模块。
3、初始化核心服务:启动 StatusBarManagerService、NavigationBarManagerService 等关键服务。
4、启动 SystemUI 应用:通过 ActivityThread 启动 SystemUIApplication,加载状态栏、导航栏等界面组件。
5、绑定服务与交互:SystemUI 与应用层通过 Binder通信(如状态栏颜色修改、通知推送)。
关键代码流程(基于AOSP源码):
1、SystemUI 的启动入口在 SystemServer.java 的 main() 方法中。系统启动时,init 进程调用 system_server 的 main() 方法,启动系统服务。
AOSP 源码(frameworks/base/services/java/com/android/server/SystemServer.java):
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
// ... 系统初始化(如时间、电源管理)
startBootstrapServices(); // 启动引导服务(如 ActivityManagerService)
startCoreServices(); // 启动核心服务(如 PackageManagerService)
startOtherServices(); // 启动其他服务(包括 SystemUI)
// ...
}
private void startOtherServices() {
// ... 其他服务启动
mSystemServiceManager.startService(StatusBarManagerService.class); // 启动状态栏服务
mSystemServiceManager.startService(NavigationBarManagerService.class); // 启动导航栏服务
// ...
startSystemUi(); // 显式启动 SystemUI 应用
}
关键方法 startSystemUi()(Android 10+):
private void startSystemUi() {
// 通过 ActivityManagerService 启动 SystemUI 的主 Activity
Intent intent = new Intent();
intent.setComponent(new ComponentName(
"com.android.systemui",
"com.android.systemui.SystemUIApplication"
));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mSystemServiceManager.startService(intent); // 实际调用 AMS 启动应用
}
2、SystemUIApplication 初始化(Android 8.0+)
SystemUIApplication 是 SystemUI 应用的入口类,负责初始化界面组件(状态栏、导航栏等)并绑定服务。
AOSP 源码(frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java):
public class SystemUIApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
// 初始化系统 UI 核心组件
initSystemUI();
}
private void initSystemUI() {
// 加载配置(如状态栏图标、导航栏布局)
Resources res = getResources();
boolean hasNavigationBar = res.getBoolean(R.bool.config_showNavigationBar);
// 初始化状态栏
mStatusBar = new StatusBar(this);
mStatusBar.init(); // 初始化状态栏视图和逻辑
// 初始化导航栏(如果设备支持)
if (hasNavigationBar) {
mNavigationBar = new NavigationBar(this);
mNavigationBar.init();
}
// 绑定通知管理服务
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.addNotificationListener(mNotificationListener, null, USER_ALL);
}
}
3、状态栏服务启动(Android 5.0~Android 13)
StatusBarManagerService 是管理系统栏的核心服务,负责处理状态栏的显示/隐藏、图标更新等逻辑。
AOSP 源码(frameworks/base/services/core/java/com/android/server/statusbar/StatusBarManagerService.java):
public class StatusBarManagerService extends IStatusBarManager.Stub {
private StatusBarManager mStatusBarManager;
@Override
public void setStatusBarColor(int color, int statusBarIconBrightness) {
// 调用本地方法更新状态栏颜色和图标亮度
nativeSetStatusBarColor(color, statusBarIconBrightness);
}
private native void nativeSetStatusBarColor(int color, int brightness);
}
系统服务注册(Android 7.0+):
// 在 SystemServer 的 startCoreServices() 中注册
mSystemServiceManager.startService(StatusBarManagerService.class);
三、SystemUI核心功能实现
1、状态栏(StatusBar)控制
示例:修改状态栏颜色与图标
public class StatusBarUtils {
public static void setStatusBarColor(Activity activity, int color) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = activity.getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(color);
// 设置状态栏图标颜色(深色背景用白色图标)
int flags = window.getDecorView().getSystemUiVisibility();
if (isLightStatusBar(activity)) {
flags |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
} else {
flags &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
}
window.getDecorView().setSystemUiVisibility(flags);
}
}
private static boolean isLightStatusBar(Activity activity) {
Drawable background = activity.getWindow().getDecorView().getBackground();
if (background instanceof ColorDrawable) {
int color = ((ColorDrawable) background).getColor();
return Color.red(color) > 128 && Color.green(color) > 128 && Color.blue(color) > 128;
}
return false;
}
}
2、隐藏系统栏(沉浸式模式)
public class FullscreenActivity extends AppCompatActivity {
private View mDecorView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fullscreen);
mDecorView = getWindow().getDecorView();
hideSystemUI();
}
private void hideSystemUI() {
int flags = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
mDecorView.setSystemUiVisibility(flags);
}
@Override
public void onWindowFocusChangeListener(boolean hasFocus) {
if (hasFocus) hideSystemUI();
}
}
3、监听系统UI可见性变化
mDecorView.setOnSystemUiVisibilityChangeListener(visibility -> {
if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
// 状态栏/导航栏显示
Log.d("SystemUI", "System bars are visible");
} else {
// 系统栏隐藏
Log.d("SystemUI", "System bars are hidden");
}
});
四、不同安卓版本之间的差异
1、Android 5.0(Lollipop)~ Android 7.1(Nougat)
状态栏与导航栏:引入沉浸式模式(SYSTEMUIFLAG_IMMERSIVE),但边缘滑动触发系统栏显示的逻辑尚未完善。通知栏使用传统布局(NotificationCompat),不支持动态布局。
代码差异:
// Android 5.0+ 设置状态栏透明
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getWindow().setStatusBarColor(Color.TRANSPARENT);
}
启动方式:SystemUI 作为独立应用启动,通过 ActivityThread 加载 SystemUIApplication。
服务管理:状态栏和导航栏服务(StatusBarManagerService、NavigationBarManagerService)直接由 SystemServer 启动。
代码差异:
// Android 5.0 启动 SystemUI 的 Intent
Intent intent = new Intent("android.intent.action.MAIN");
intent.setComponent(new ComponentName(
"com.android.systemui",
"com.android.systemui.SystemUIApplication"
));
2、Android 8.0(Oreo)~ Android 10(Q)
通知渠道:强制要求应用创建通知渠道(NotificationChannel)。
分区存储:外部存储访问需适配 Scoped Storage(Android 10+)。
代码差异:
// Android 8.0+ 创建通知渠道
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(
"channel_id", "Channel Name", NotificationManager.IMPORTANCE_DEFAULT);
channel.setDescription("Channel Description");
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(channel);
}
模块化增强:引入 SystemUIFactory
动态加载模块(如状态栏图标、通知布局)。
服务绑定优化:通过 Binder
实现跨进程通信(如应用修改状态栏需调用 StatusBarManager
)。
代码差异:
// Android 8.0+ 动态加载状态栏模块
public class StatusBarManager {
public void loadModule(String moduleName) {
// 从 /system/lib/systemui/ 加载模块 APK
System.loadLibrary(moduleName);
}
}
3、Android 11(R)~ Android 13(Tiramisu)
作用域存储:Scoped Storage 强制生效,外部存储访问需使用 Storage Access Framework。
沉浸式模式增强:支持边缘到边缘(Edge-to-Edge)显示,需配合 WindowInsetsController。引入 WindowInsetsController
替代 View.setSystemUiVisibility()
。
代码差异:
// Android 11+ 边缘到边缘适配
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
WindowInsetsController controller = getWindow().getInsetsController();
controller.hide(WindowInsets.Type.statusBars() | WindowInsets.Type.navigationBars());
getWindow().setDecorFitsSystemWindows(false);
}else {
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN);
}
4、Android 14(Upside Down Cake)
状态栏图标架构重构:引入 Pipeline 架构,将状态栏图标分为数据层、域层、UI 层(搜索结果),旧版 NetworkController 被废弃,改用 StatusBarPipelineFlags 控制图标刷新。
代码差异:
// Android 14+ 状态栏图标新架构
StatusBarPipelineFlags flags = new StatusBarPipelineFlags();
if (flags.useMobileIcons()) {
// 使用新架构加载 Mobile 图标
MobileIconController mobileIconController = new MobileIconController(context);
mobileIconController.updateIcon(networkType);
}
借鉴与有关博客:
systemUI的详细介绍:Android SystemUI(一):图文并茂的介绍 :D-腾讯云开发者社区-腾讯云
systemUI简介以及启动流程:Android 车载应用开发指南 - SystemUI-CSDN博客
修改 systemUI步骤:Android修改 systemui_mob649e81547b8f的技术博客_51CTO博客
systemUI的简介、启动和初始化:Android SystemUI梳理_51CTO博客_android.systemui
systemUI的启动:SystemUI分析 - cascle - 博客园
systemUI的前世今生与主要组件:Android SystemUI篇(一)-CSDN博客