美文网首页
SystemUI之VolumeUI启动流程

SystemUI之VolumeUI启动流程

作者: Soetsu | 来源:发表于2018-08-16 19:22 被阅读0次

SystemUI启动时通过startServicesIfNeeded(Class<?>[] services) 方法,调用所有继承SystemUI类的service的start()方法,VolumeUI也是其中之一。

    public void start() {
        //可以通过config配置是否启用volume ui
        mEnabled = mContext.getResources().getBoolean(R.bool.enable_volume_ui);
        if (!mEnabled) return;
        //初始化VolumeDialogComponent元件
        mVolumeComponent = new VolumeDialogComponent(this, mContext, null);
        putComponent(VolumeComponent.class, getVolumeComponent());
        //注册controller
        setDefaultVolumeController();
    }

1. VolumeDialogComponent

start()方法会初始化一个VolumeDialogComponent元件,后面其实注册controller也是由该元件来操作的,所以先看下它的构造函数:

    public VolumeDialogComponent(SystemUI sysui, Context context, Handler handler) {
        mSysui = sysui;
        mContext = context;
        //通过Dependency实例化VolumeDialogController接口
        mController = (VolumeDialogControllerImpl) Dependency.get(VolumeDialogController.class);
        mController.setUserActivityListener(this);
        // Allow plugins to reference the VolumeDialogController.
        //允许插件引用VolumeDialogController。
        Dependency.get(PluginDependencyProvider.class)
                .allowPluginDependency(VolumeDialogController.class);
        //初始化一个扩展工具
        mExtension = Dependency.get(ExtensionController.class).newExtension(VolumeDialog.class)
                .withPlugin(VolumeDialog.class)
                //重写了Supplier<T>的get()方法
                //createDefault()方法返回了一个VolumeDialogImpl实例化对象
                .withDefault(this::createDefault)
                //重写了Consumer<T>的accept()方法
                //上面两个重写的方法均会在configuration change时通过mExtension的reload()方法里调用
                .withCallback(dialog -> {
                    if (mDialog != null) {
                        mDialog.destroy();
                    }
                    mDialog = dialog;
                    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);
    }

从以上代码可以看到,实例化mVolumeComponent 的时候,相当于进行了一系列插件的初始化。初始化mExtension的时候通过withDefault和withCallback传入的Supplier和Consumer对象,会在onConfigurationChanged()的时候,通过自身的reload()方法,重新初始化dialog的一些配置。

2. VolumeDialogControllerImpl

前面说到过注册controller也是由VolumeDialogComponent元件来实现的,那么接下来再看下setDefaultVolumeController()。

    private void setDefaultVolumeController() {
        DndTile.setVisible(mContext, true);
        if (LOGD) Log.d(TAG, "Registering default volume controller");
        getVolumeComponent().register();
    }

先把勿扰模式Tile设置可见,随后在VolumeComponent的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);
        }
    }
  • setVolumeController():
    mVolumeController是IVolumeController接口的实例,里面实现了一系列AudioService的回调函数。这个方法是主动去向AudioService注册自己的VolumeController,后续音量调节也是通过这个VolumeController来完成UI更新的。
mAudio.setVolumeController(mVolumeController);
  • setVolumePolicy():
    通过AudioManager更新VolumePolicy
  • showDndTile():
    设置勿扰模式DndTile可见
  • mMediaSessions.init():
    初始化多媒体播放框架

3. 小结

VolumeUI的启动流程基本是各种插件、工具和controller的初始化过程,后续framework处理到音量变化的事件时会通过AudioService回调这些controller来更新音量UI,即SystemUI的VolumeDialog只在有音量相关改变的时候才会显示。

相关文章

网友评论

      本文标题:SystemUI之VolumeUI启动流程

      本文链接:https://www.haomeiwen.com/subject/drznbftx.html