其他分享
首页 > 其他分享> > 关于Android5.0上SeekBar的一个BUG

关于Android5.0上SeekBar的一个BUG

作者:互联网

关于Android5.0上SeekBar的一个BUG

最近在做Android5.0的系统APP定制,遇到一个SeekBar拖动无效的问题,进过分析定位发现是由于在异步线程创建SeekBar导致,对应问题demo

接下是该问题的具体分析:


1.SeekBar代码结构

这里写图片描述

可以看到SeekBar继承了AbsAeekBar,而AbsAeekBar又继承了ProgressBar
拖动SeekBar涉及到的方法主要有onTouchEvent、trackTouchEvent、setProgressInternal、refreshProgress、doRefreshProgress

2.SeekBar拖动处理流程

这里写图片描述

1.拖动SeekBar会调用onTouchEvent方法跟踪触摸滑动
2.通过trackTouchEvent将触摸滑动后的距离转换为对应进度值
3.通过setProgressInternal来通知ProgressBar来设置进度
4.通过refreshProgress、doRefreshProgress来刷新界面显示进度值
5.通过onProgre***efresh来通知进度值发生了改变

3.出现问题的原因

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

1.在触摸滑动后,通过refreshProgress刷新界面进度值时,会判断当前线程与创建SeekBar的线程是否一致,触摸滑动对应的是UI线程,如果SeekBar是在异步线程创建,则mUiThreadId与UI线程不对应,从而导致需要通过post(mRefreshProgre***unnable)来回到UI线程做进度条刷新处理
2.如果在执行了post(mRefreshProgre***unnable)后,立刻触发了onDetachedFromWindow则会调用removeCallbacks(mRefreshProgre***unnable)删除还未执行的任务,从而导致标志位mRefreshIsPosted没有设置为false
3.在标志位mRefreshIsPosted为false后,以后再触摸滑动进度条,通过refreshProgress刷新界面进度值时再也不能刷新进度条变化了

4.与Android8.0相比较

这里写图片描述

可以看到在触发onDetachedFromWindow后,删除了待执行任务,同时将标志位mRefreshIsPosted设置为false,从而解决了该问题。

标签:Android5.0,SeekBar,触摸,refreshProgress,线程,进度,滑动,BUG
来源: https://blog.51cto.com/u_15091798/2782932