Android系统中有3个非常重要的应用,分别是SystemUI,launcher,Setting
Android 的 SystemUI 其实就是 Android 的系统界面,它包括了界面上方的状态栏 status bar,下方的导航栏Navigation Bar,锁屏界面 Keyguard ,电源界面 PowerUI,近期任务界面 Recent Task 等等。对于用户而言,SystemUI 的改动是最能直观感受到的。因此,每个 Android 版本在 SystemUI 上都有比较大的改动。而对开发者而言,理解 Android SystemUI 对优化Android系统界面,改善用户体验十分重要。
Android系统在启动系统服务器SystemService的时候,会启动各个服务器,而在启动这个服务器之后会启动launcher和SystemUI
frameworks/base/services/java/com/android/server/SystemServer.java
public final class SystemServer {
private void run() {
startBootstrapServices();
startCoreServices();
startOtherServices();
}
private void startOtherServices() {
// 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(() -> {
startSystemUi(context, windowManagerF);
}
}
}
可以看出在系统在启动所有服务器之后,监听mActivityManagerService状态,如果“systemReady”后,启动SytemUI,AMS的systemReady先启动SystemUI之后启动launcher,我们这里只关注SystemUI
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();
}
可以看见启动的是SystemUI的服务,然后调用 windowManager.onSystemUiStarted();
windowManager.onSystemUiStarted();执行了下面的流程
public void bindService(Context context) {
context.bindServiceAsUser(intent, mKeyguardConnection,//注1
Context.BIND_AUTO_CREATE, mHandler, UserHandle.SYSTEM)
}
注1:这里的intent是SystemUI的keygaurdServUC儿,通过获取SystemUI的keyguard,控制SystemU的锁屏。
SystemUIService类十分简短,下面基本就是他全部的代码,
public class SystemUIService extends Service {
@Override
public void onCreate() {
super.onCreate();
((SystemUIApplication) getApplication()).startServicesIfNeeded();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
他只是调用SystemUIApplication的startServicesIfNeeded方法
public class SystemUIApplication extends Application implements SysUiServiceProvider {
public void startServicesIfNeeded() {
String[] names = getResources().getStringArray(R.array.config_systemUIServiceComponents);
startServicesIfNeeded(names);
}
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();//new it
} 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;
}
}
可以看到他通过反射实例化config_systemUIServiceComponents数组对应的“service”,然后调用start方法。
config_systemUIServiceComponents有哪些呢?
- com.android.systemui.Dependency
- com.android.systemui.util.NotificationChannels
- com.android.systemui.statusbar.CommandQueue$CommandQueueStart
- com.android.systemui.keyguard.KeyguardViewMediator
- com.android.systemui.recents.Recents
- com.android.systemui.volume.VolumeUI
- com.android.systemui.stackdivider.Divider
- com.android.systemui.SystemBars
- com.android.systemui.usb.StorageNotification
- com.android.systemui.power.PowerUI
- com.android.systemui.media.RingtonePlayer
- com.android.systemui.keyboard.KeyboardUI
- com.android.systemui.pip.PipUI
- com.android.systemui.shortcut.ShortcutKeyDispatcher
- @string/config_systemUIVendorServiceComponent
- com.android.systemui.util.leak.GarbageMonitor$Service
- com.android.systemui.LatencyTester
- com.android.systemui.globalactions.GlobalActionsComponent
- com.android.systemui.ScreenDecorations
- com.android.systemui.fingerprint.FingerprintDialogImpl
- com.android.systemui.SliceBroadcastRelayHandler
这些类继承SystemUI,SystemUI类又是干什么的呢?
这个应用主要界面都是显示在Android屏幕部分区域,这些界面没有通过Activity控制,SystemUI类具有管理的功能,如在屏幕旋转会调用onConfigurationChanged方法,各个界面就可以做出相应的显示,调用onstar启动相应的模块。
各个模块比较多,已SystemBars为例进行分析。在startServicesIfNeeded方法中会实例化这个模块,然后调用其start方法。
SystemBars类(去除不重要的代码,以及log)
public class SystemBars extends SystemUI {
@Override
public void start() {
createStatusBarFromConfig();
}
private void createStatusBarFromConfig() {
//
final String clsName =com.android.systemui.statusbar.phone.StatusBar mContext.getString(R.string.config_statusBarComponent);
Class> cls = null;
cls = mContext.getClassLoader().loadClass(clsName);
mStatusBar = (SystemUI) cls.newInstance();
mStatusBar.mContext = mContext;
mStatusBar.mComponents = mComponents;
mStatusBar.start();
}
}
SystemBars实例化了R.string.config_statusBarComponent对应的com.android.systemui.statusbar.phone.StatusBar这个类,并调用其start方法。
public class StatusBar extends SystemUI{
@Override
public void start() {
createAndAddWindows();
}
public void createAndAddWindows() {
addStatusBarWindow();
}
private void addStatusBarWindow() {
makeStatusBarView();
mStatusBarWindowManager = Dependency.get(StatusBarWindowManager.class);
mRemoteInputManager.setUpWithPresenter(this, mEntryManager, this,
new RemoteInputController.Delegate() {
public void setRemoteInputActive(NotificationData.Entry entry,
boolean remoteInputActive) {
mHeadsUpManager.setRemoteInputActive(entry, remoteInputActive);
entry.row.notifyHeightChanged(true /* needsAnimation */);
updateFooter();
}
public void lockScrollTo(NotificationData.Entry entry) {
mStackScroller.lockScrollTo(entry.row);
}
public void requestDisallowLongPressAndDismiss() {
mStackScroller.requestDisallowLongPress();
mStackScroller.requestDisallowDismiss();
}
});
mRemoteInputManager.getController().addCallback(mStatusBarWindowManager);
mStatusBarWindowManager.add(mStatusBarWindow, getStatusBarHeight());
}
protected void inflateStatusBarWindow(Context context) {
mStatusBarWindow = (StatusBarWindowView) View.inflate(context,
R.layout.super_status_bar, null);
}
}
最后通过inflateStatusBarWindow获取view,然后mStatusBarWindowManager添加这个view,并显示出来。
SystemBars加载基本全部SystemUI的界面显示,由于布局太多,查找起来十分麻烦,我从其他人那里copy过来,链接:++https://www.jianshu.com/p/2e0f403e5299++