SystemUI中有很多的模块,在之前的篇章里已经对有的模块进行了分析,这次我们来看到VolumeUI
相关
同样的,我们需要找到VolumeUI.java,然后我们可以看到在其中有一个start方法
@Override
public void start() {
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;
mVolumeComponent.setEnableDialogs(enableVolumeUi, enableSafetyWarning);
setDefaultVolumeController();
}
首先因为VolumeUI也是继承的SystemUI,所以在start方法上面有一个@Override的注解。这里主要看到setDefaultVolumeController,在这个方法里面注册了一个默认的音量控制器
private void setDefaultVolumeController() {
DndTile.setVisible(mContext, true);
if (D.BUG) Log.d(TAG, "Registering default volume controller");
mVolumeComponent.register();
}
它调用了VolumeDialogComponent的register方法,但是实际上是调用了VolumeDialogControllerImpl的register方法
public void register() {
setVolumeController();
setVolumePolicy(mVolumePolicy);
showDndTile(mShowDndTile);
try {
mMediaSessions.init();
} catch (SecurityException e) {
Log.w(TAG, "No access to media sessions", e);
}
}
1.他初始化了dialog,设置了dialog布局
2.添加VolumeDialogImpl回调,分发handle消息让dialog去相应对应事件
通过它我们就可以启动VolumeUI功能了。
那么我们怎么启动它呢,首先我们可以看到VolumeUI的构造就是将VolumeDialogComponent实例化,所以我们看到VolumeDialogComponent的构造方法
public VolumeDialogComponent(Context context, KeyguardViewMediator keyguardViewMediator,
VolumeDialogControllerImpl volumeDialogController) {
mContext = context;
mKeyguardViewMediator = keyguardViewMediator;
mController = volumeDialogController;
mController.setUserActivityListener(this);
// Allow plugins to reference the VolumeDialogController.
Dependency.get(PluginDependencyProvider.class)
.allowPluginDependency(VolumeDialogController.class);
Dependency.get(ExtensionController.class).newExtension(VolumeDialog.class)
.withPlugin(VolumeDialog.class)
.withDefault(this::createDefault)
.withCallback(dialog -> {
if (mDialog != null) {
mDialog.destroy();
}
mDialog = dialog;
mDialog.init(LayoutParams.TYPE_VOLUME_OVERLAY, mVolumeDialogCallback);
}).build();
applyConfiguration();
Dependency.get(TunerService.class).addTunable(this, VOLUME_DOWN_SILENT, VOLUME_UP_SILENT,
VOLUME_SILENT_DO_NOT_DISTURB);
}
在这里又使用了createDefault方法实例化了VolumeDialogImpl对象,用init进行初始化。这里会向VolumeDialogController注册一个回调并注册一个新的handle
并且,在VolumeDialogControllerImpl中还有一个setVolumeController方法,这个方法设置了AudioManager,也就是model。
protected void setVolumeController() {
try {
mAudio.setVolumeController(mVolumeController);
} catch (SecurityException e) {
Log.w(TAG, "Unable to set the volume controller", e);
return;
}
}
启动
systemUI的启动基本都是在service中进行第一步,所以我们找到
public class SystemUIService extends Service {
...
@Override
public void onCreate() {
super.onCreate();
((SystemUIApplication) getApplication()).startServicesIfNeeded();
}
...
}
在这个方法里面,我们的SystemUIApplication会通过startServicesIfNeeded读取配置文件去启动所有的SystemUI。接下来的步骤,上文都有列出。