SystemUI添加第三方快捷开关时灰显问题分析

来源:互联网 发布:keep软件免费下载 编辑:程序博客网 时间:2024/06/07 03:17

作者:neek.chen

Android7.0上不仅有默认的快捷快关(QSTile),也允许客户自行添加第三方快捷开关(CustomTile)。本文只介绍在绑定第三方CustomTile时遇到的间歇性灰显的问题。

问题场景描述:

    进SystemUI的编辑界面,将一个第三方Tile添加到显示列表中,返回显示界面,间歇性出现图标是不可用状态(灰显)。

添加Tile流程分析

1. 将CustomTile添加到显示区,点击返回,会执行保存和更新Tile的操作,距离流程见下图:

这里写图片描述
在changeTiles()中会对比之前的Tile列表,若有新增的或是删除的,则需要通知对应APP做相应的更新操作。对于新增的Tile,会通过flushMessagesAndUnbind()去执行绑定service的操作。
2. 同时,在QSTileHost中实现了Tunable的onTuningChanged()接口,所以相继也会调用该接口。该函数实现的功能和changeTiles()差不多,对比保存前后的列表差异,销毁已经删除的Tile对象,创建新添加的Tile对象。

两个流程的差异

changeTiles()和onTuningChanged()触发间隔相差几十毫秒

  1. changeTiles()会去绑定service,绑定成功后又立即解绑。——addTile
  2. onTuningChange()会创建CutomTile对象,并启动监听,启动监听也需要绑定service。——startListening

addTile 和 startListening 会分别触发onTileAdded()和onStartListening()两个回调给应用。一般的应用会在两个回调用去获得该Tile对象:getTile(),以便后续的状态更新,应用如果拿到对象为NULL就无法更新状态,即灰显。

问题原因

addTile执行bindService时,因为CustomTile对象还没创键,所以第三方应用第一次在onTileAdded()中调用getTile()获得的对象一定为空。 期间,如果在addTile还未执行unbind时,就开始执行startListening的bindService,致使unbind在最后执行,就会导致服务和应用最终处于解绑状态,无法更新。

**

解决方案

  1. 去掉changeTiles()
    刚开始分析时,个人觉得changeTiles()的功能和onTuningChange()的内容基本一样,有点重复的意味。所以把它注释掉了,运行起来也没问题,未发现对功能有什么影响。但是,在CTS测试时,会导致所有SystemUI的测试项Failed。
  2. 添加延时
    在CustomTile的setListening()中,将原先的绑定service和启动监听添加一个延时:
    private void bindingTileService(){        LogUtils.v(TAG+"--TileNeek", "bindingTileService(" + mComponent.getClassName()+") delay " + CHANGE_TILE_DELAY);        mTileHandle.removeCallbacks(tileBindRunnable);        mTileHandle.postDelayed(tileBindRunnable,CHANGE_TILE_DELAY);    }    Runnable tileBindRunnable = new Runnable() {        @Override        public void run() {            try {                LogUtils.v(TAG+"--TileNeek", "-----run for " + mComponent.getClassName());                mServiceManager.setBindRequested(true);                mService.onStartListening();            } catch (RemoteException e) {                e.printStackTrace();            }        }    };

总结

刚接触SystemUI半年,好多底层逻辑流程还一知半解,只能用到哪看到哪。就这个问题而言,暂时还搞不清楚为什么要在changeTiles()中执行flushMessagesAndUnbind()绑定有立即解绑的意义在哪?所以最终改换第二套方案,规避掉绑定时间差导致的不可用问题。希望有大神可以赐教。

原创粉丝点击