这里分析的是Android 9的源代码
启动篇(1)
SystemServer.java
1.执行main函数,开始跑线程
public static void main(String[] args) {
new SystemServer().run();
}
2.执行startOtherServices函数
private void run() {
// Start services.
try {
traceBeginAndSlog("StartServices");
startBootstrapServices();
startCoreServices();
startOtherServices();
} catch (Throwable ex) {
throw ex;
} finally {
traceEnd();
}
}
3.执行startSystemUi函数
private void startOtherServices(){
traceBeginAndSlog("StartSystemUI");
try {
startSystemUi(context, windowManagerF);
}
catch (Throwable e) {
reportWtf("starting System UI", e);
}
traceEnd();
}
4.开始拉起systemUIService服务,并且WindowManagerService也调用onSystemUiStarted方法
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);
context.startServiceAsUser(intent, UserHandle.SYSTEM);
windowManager.onSystemUiStarted();
}
WindowManagerService.java
5.这里面的 windowManager实际上是PhoneWindowManager,
public void onSystemUiStarted() {
mPolicy.onSystemUiStarted();
}
KeyguardServiceDelegate.java
6.最终跟到源码里面,它做的事情就是PhoneWindowManager与锁屏服务做了bindService的操作,这块我们就不再跟下去了,接下来我们主要去看看SystemUIService都做了什么操作
public void bindService(Context context) {
Intent intent = new Intent();
final Resources resources = context.getApplicationContext().getResources();
final ComponentName keyguardComponent = ComponentName.unflattenFromString(
resources.getString(com.android.internal.R.string.config_keyguardComponent));
intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
intent.setComponent(keyguardComponent);
//对应的是锁屏服务,com.android.systemui.keyguard.KeyguardService
if (!context.bindServiceAsUser(intent, mKeyguardConnection,
Context.BIND_AUTO_CREATE, mHandler, UserHandle.SYSTEM)) {
Log.v(TAG, "*** Keyguard: can't bind to " + keyguardComponent);
} else {
if (DEBUG) Log.v(TAG, "*** Keyguard started");
}
}
SystemUIService.java
7.SystemUI是一个app,是一个persistent 应用
SystemUIService它直接调用的是SystemUIApplication的startServicesIfNeeded
public void onCreate() {
((SystemUIApplication) getApplication()).startServicesIfNeeded();
}
SystemUIApplication.java
8.SystemUIApplication的startServicesIfNeeded函数
public void startServicesIfNeeded() {
String[] names =getResources().getStringArray(R.array.config_systemUIServiceComponents);
startServicesIfNeeded(names);
}
9.启动以下系统组件
<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>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>
UML类图(systemui组件)
10.启动上面的systemui的组件,它们都是继承于systemui的类,其组件架构如下图
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];
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;
//调用组件的start方法,如果组件启动超过1秒,会有打印
mServices[i].start();
ti = System.currentTimeMillis() - ti;
if (ti > 1000) {
Log.w(TAG, "Initialization of " + cls.getName() + " took " + ti + " ms");
}
//如果系统重启成功,调用组件的onBootCompleted方法
if (mBootCompleted) {
mServices[i].onBootCompleted();
}
}
//获取PluginManagerImpl对象,并添加插件监听
Dependency.get(PluginManager.class).addPluginListener(
new PluginListener<OverlayPlugin>() {
private ArraySet<OverlayPlugin> mOverlays;
@Override
public void onPluginConnected(OverlayPlugin plugin, Context pluginContext) {
StatusBar statusBar = getComponent(StatusBar.class);
if (statusBar != null) {
plugin.setup(statusBar.getStatusBarWindow(),
statusBar.getNavigationBarView());
}
// Lazy init.
if (mOverlays == null) mOverlays = new ArraySet<>();
if (plugin.holdStatusBarOpen()) {
mOverlays.add(plugin);
Dependency.get(StatusBarWindowManager.class).setStateListener(b ->
mOverlays.forEach(o -> o.setCollapseDesired(b)));
Dependency.get(StatusBarWindowManager.class).setForcePluginOpen(
mOverlays.size() != 0);
}
}
@Override
public void onPluginDisconnected(OverlayPlugin plugin) {
mOverlays.remove(plugin);
Dependency.get(StatusBarWindowManager.class).setForcePluginOpen(
mOverlays.size() != 0);
}
}, OverlayPlugin.class, true /* Allow multiple plugins */);
mServicesStarted = true;
}
总结:从代码流程来看,其实相对来说还是很简单的。SystemServer启动后,会启动SystemUI服务,启动SystemSUI服务的同时,锁屏相关的服务也会拉起,而SystemUI启动的核心内容其实也就是各组件启动的过程。下面我将带大家看看其中的VolumeUI组件,也就是大家熟悉的音量条组件。
组件篇Dependency(2)
Dependency.java
1.书接上文,我们知道SystemUI应用里面有很多继承于SystemUI类的组件,其中Dependency就是第一个组件
public class Dependency extends SystemUI {
//依赖对象的映射缓存列表
private final ArrayMap<Object, Object> mDependencies = new ArrayMap<>();
//cls<->数据提供者的映射列表
private final ArrayMap<Object, DependencyProvider> mProviders = new ArrayMap<>();
}
2.执行start函数,先将Controller和ControllerImpl的映射关系放到mProviders中,后续get函数要用mProviders的数据
public void start() {
//初使化数据
mProviders.put(PluginManager.class, () -> new PluginManagerImpl(mContext));
mProviders.put(StatusBarIconController.class, () -> new StatusBarIconControllerImpl(mContext));
...
mProviders.put(VolumeDialogController.class, () -> new VolumeDialogControllerImpl(mContext));
...
//将所有依赖项放在上面,这样工厂就可以根据需要覆盖它们。
SystemUIFactory.getInstance().injectDependencies(mProviders, mContext);
sDependency = this;
}
3.get函数,实际上是从拿到的也就是mProviders中put的xxxControllerImpl。这里的mDependencies充当了缓存的作用,只有当用到的时候才会实现xxxControllerImpl,并放到内存中
public static <T> T get(Class<T> cls) {
return sDependency.getDependency(cls);
}
protected final <T> T getDependency(Class<T> cls) {
return getDependencyInner(cls);
}
private synchronized <T> T getDependencyInner(Object key) {
@SuppressWarnings("unchecked")
T obj = (T) mDependencies.get(key);
if (obj == null) {
//如果没有mDependencies,就创建一个
obj = createDependency(key);
mDependencies.put(key, obj);
}
return obj;
}
4.createDependency函数,实际上拿到的就是上面的xxxControllerImpl.
@VisibleForTesting
protected <T> T createDependency(Object cls) {
Preconditions.checkArgument(cls instanceof DependencyKey<?> || cls instanceof Class<?>);
@SuppressWarnings("unchecked")
//拿到数据的提供者
DependencyProvider<T> provider = mProviders.get(cls);
if (provider == null) {
throw new IllegalArgumentException("Unsupported dependency " + cls
+ ". " + mProviders.size() + " providers known.");
}
//通过数据提供者创建依赖关系
return provider.createDependency();
}
5.通知mDependencies缓存中各继承了ConfigurationChangedReceiver接口组件的xxxControllerImpl,并回调它们的onConfigurationChanged
@Override
protected synchronized void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mDependencies.values().stream().filter(obj -> obj instanceof ConfigurationChangedReceiver)
.forEach(o -> ((ConfigurationChangedReceiver) o).onConfigurationChanged(newConfig));
}
总结:其实Dependency就是维护了一个数据对象数据集而已,方便统一调用共有的函数,也方便其他的类做一个对象引用,
组件篇VolumeUI(3)
VolumeUI.java
1.书接上文,我们知道SystemUI应用里面有很多继承于SystemUI类的组件,其中VolumeUI就是之一
public class VolumeUI extends SystemUI
2.执行start函数
public void start() {
//先判断VolumeUI能不能用
boolean enableVolumeUi = mContext.getResources().getBoolean(R.bool.enable_volume_ui);
boolean enableSafetyWarning =
mContext.getResources().getBoolean(R.bool.enable_safety_warning);
mEnabled = enableVolumeUi || enableSafetyWarning;
if (!mEnabled) return;
//VolumeUI 绑定实际的组件 VolumeDialogComponent
mVolumeComponent = new VolumeDialogComponent(this, mContext, null);
mVolumeComponent.setEnableDialogs(enableVolumeUi, enableSafetyWarning);
//添加映射关系到组件列表
putComponent(VolumeComponent.class, mVolumeComponent);
//组件注册
mVolumeComponent.register();
}
VolumeDialogComponent.java
3.我们来看看VolumeDialogComponent的构造函数
public VolumeDialogComponent(SystemUI sysui, Context context, Handler handler) {
mSysui = sysui;
mContext = context;
//这里我们可以看到实际引用是VolumeDialogControllerImpl
mController = (VolumeDialogControllerImpl) Dependency.get(VolumeDialogController.class);
//如果发生了用户活动,就会通知电源管理器PowerManager
mController.setUserActivityListener(this);
//允许插件引用VolumeDialogController
//PluginDependencyProvider-->PluginDependencyProvider-->PluginManagerImpl
//将VolumeDialogControllerImpl放到PluginDependencyProvider的mDependencies中
Dependency.get(PluginDependencyProvider.class)
.allowPluginDependency(VolumeDialogController.class);
//初始化一个扩展工具,用于VolumeDialogImpl(View)的初使化,
Dependency.get(ExtensionController.class)
.newExtension(VolumeDialog.class)
.withPlugin(VolumeDialog.class)
.withDefault(this::createDefault)//createDefault()方法返回了一个VolumeDialogImpl实例化对象
.withFeature(PackageManager.FEATURE_AUTOMOTIVE, this::createCarDefault)
.withCallback(dialog -> {
if (mDialog != null) {
mDialog.destroy();
}
mDialog = dialog;
//基实VolumeDialogImpl就是在这个地方完成了初使化的回调
mDialog.init(LayoutParams.TYPE_VOLUME_OVERLAY, mVolumeDialogCallback);
}).build();
applyConfiguration();
//注册Observer监听,并回调自己的onTuningChanged(),更新mVolumePolicy
Dependency.get(TunerService.class).addTunable(this, VOLUME_DOWN_SILENT, VOLUME_UP_SILENT,
VOLUME_SILENT_DO_NOT_DISTURB);
}
//start函数会固定执行register
@Override
public void register() {
mController.register();
DndTile.setCombinedIcon(mContext, true);
}
//VolumeDialog的具体实现是VolumeDialogImpl
private VolumeDialog createDefault() {
VolumeDialogImpl impl = new VolumeDialogImpl(mContext);
impl.setStreamImportant(AudioManager.STREAM_SYSTEM, false);
impl.setAutomute(true);
impl.setSilentMode(false);
return impl;
}
VolumeDialogControllerImpl.java(Presenter层)
4.我们来看看VolumeDialogControllerImpl的构造函数
protected final VC mVolumeController = new VC();
public VolumeDialogControllerImpl(Context context) {
mContext = context.getApplicationContext();
mNotificationManager = (NotificationManager) mContext.getSystemService(
Context.NOTIFICATION_SERVICE);
//打印事件log
Events.writeEvent(mContext, Events.EVENT_COLLECTION_STARTED);
//子线程的handler
mWorkerThread = new HandlerThread(VolumeDialogControllerImpl.class.getSimpleName());
mWorkerThread.start();
mWorker = new W(mWorkerThread.getLooper());
//获取mMediaSessions
mMediaSessions = createMediaSessions(mContext, mWorkerThread.getLooper(),
mMediaSessionsCallbacksW);
//获取AudioManager
mAudio = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
mNoMan = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
mObserver = new SettingObserver(mWorker);
mObserver.init();
mReceiver.init();
//获取震动对象
mVibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
mHasVibrator = mVibrator != null && mVibrator.hasVibrator();
//获取AudioService
mAudioService = IAudioService.Stub.asInterface(
ServiceManager.getService(Context.AUDIO_SERVICE));
//更新statusBar
updateStatusBar();
//更新声音控制的策略
boolean accessibilityVolumeStreamActive = context.getSystemService(
AccessibilityManager.class).isAccessibilityVolumeStreamActive();
//这时的mVolumeController是
mVolumeController.setA11yMode(accessibilityVolumeStreamActive ?
VolumePolicy.A11Y_MODE_INDEPENDENT_A11Y_VOLUME :
VolumePolicy.A11Y_MODE_MEDIA_A11Y_VOLUME);
}
5.再看看他的register
//
public void register() {
//设置音量控制器
setVolumeController();
setVolumePolicy(mVolumePolicy);
showDndTile(mShowDndTile);
try {
mMediaSessions.init();
} catch (SecurityException e) {
Log.w(TAG, "No access to media sessions", e);
}
}
//将AIDL的control对象通过AudioManager传给AudioService内部,这样就实现了与AudioService的联动
protected void setVolumeController() {
try {
mAudio.setVolumeController(mVolumeController);
} catch (SecurityException e) {
Log.w(TAG, "Unable to set the volume controller", e);
return;
}
}
//AIDL对象
private final class VC extends IVolumeController.Stub {
//AudioService的一些内部回调,会回到这里,再通过mWorker(handler)对象传给本线程来处理
@Override
public void volumeChanged(int streamType, int flags) throws RemoteException {
mWorker.obtainMessage(W.VOLUME_CHANGED, streamType, flags).sendToTarget();
}
}
//当 AudioService内部触发了onVolumeChanged时,就会通过mWorker回调给本线程的onVolumeChangedW来处理
boolean onVolumeChangedW(int stream, int flags) {
final boolean showUI = shouldShowUI(flags);
final boolean fromKey = (flags & AudioManager.FLAG_FROM_KEY) != 0;
final boolean showVibrateHint = (flags & AudioManager.FLAG_SHOW_VIBRATE_HINT) != 0;
final boolean showSilentHint = (flags & AudioManager.FLAG_SHOW_SILENT_HINT) != 0;
boolean changed = false;
if (showUI) {
changed |= updateActiveStreamW(stream);
}
int lastAudibleStreamVolume = getAudioManagerStreamVolume(stream);
changed |= updateStreamLevelW(stream, lastAudibleStreamVolume);
changed |= checkRoutedToBluetoothW(showUI ? AudioManager.STREAM_MUSIC : stream);
if (changed) {
mCallbacks.onStateChanged(mState);
}
if (showUI) {
//如果要显示UI的话,就会通过mCallbacks回调出去,onShowRequested
mCallbacks.onShowRequested(Events.SHOW_REASON_VOLUME_CHANGED);
}
if (showVibrateHint) {
mCallbacks.onShowVibrateHint();
}
if (showSilentHint) {
mCallbacks.onShowSilentHint();
}
if (changed && fromKey) {
Events.writeEvent(mContext, Events.EVENT_KEY, stream, lastAudibleStreamVolume);
}
return changed;
}
6.那Callback从哪里来的呢,可以看到callback是内部的监听器,外部的想要监听变化的对象,都可以通过addCallback函数添加到内部管理的hashmap里面
protected C mCallbacks = new C();
public void addCallback(Callbacks callback, Handler handler) {
mCallbacks.add(callback, handler);
callback.onAccessibilityModeChanged(mShowA11yStream);
}
class C implements Callbacks {
private final HashMap<Callbacks, Handler> mCallbackMap = new HashMap<>();
public void add(Callbacks callback, Handler handler) {
if (callback == null || handler == null) throw new IllegalArgumentException();
mCallbackMap.put(callback, handler);
}
public void remove(Callbacks callback) {
mCallbackMap.remove(callback);
}
@Override
public void onShowRequested(final int reason) {
for (final Map.Entry<Callbacks, Handler> entry : mCallbackMap.entrySet()) {
entry.getValue().post(new Runnable() {
@Override
public void run() {
entry.getKey().onShowRequested(reason);
}
});
}
}
}
AudioManager.java(Model层)
public void setVolumeController(IVolumeController controller) {
try {
getService().setVolumeController(controller);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
VolumeDialogImpl.java(View层)
7.那我们来看看都有谁addCallback了,其中有就VolumeDialogImpl.java
public VolumeDialogImpl(Context context) {
//通过Dependency拿到VolumeDialogControllerImpl对象
mController = Dependency.get(VolumeDialogController.class);
}
public void init(int windowType, Callback callback) {
initDialog();
mAccessibility.init();
//往VolumeDialogControllerImpl对象里面添加mControllerCallbackH的监听
mController.addCallback(mControllerCallbackH, mHandler);
mController.getState();
}
private final VolumeDialogController.Callbacks mControllerCallbackH
= new VolumeDialogController.Callbacks() {
@Override
public void onShowRequested(int reason) {
//收到VolumeDialogControllerImpl的onShowRequested回调以后,就调用show函数
showH(reason);
}
};
private void showH(int reason) {
if (D.BUG) Log.d(TAG, "showH r=" + Events.DISMISS_REASONS[reason]);
mHandler.removeMessages(H.SHOW);
mHandler.removeMessages(H.DISMISS);
rescheduleTimeoutH();
mShowing = true;
initSettingsH();
//最终在这里进行了dialog的展示
mDialog.show();
Events.writeEvent(mContext, Events.EVENT_SHOW_DIALOG, reason, mKeyguard.isKeyguardLocked());
mController.notifyVisible(true);
}
UML类图(VolumeUI)
总结:到了这里,我们大概可以掌握systemui的启动,以及systemui内部的组件是怎么关联调用的。