背景
在安卓开发中,经常会遇到这样的问题:快速点击某个按钮的时候,由于点击事件中有异步操作、或者必须放在主线程但是又比较耗时的操作时,会出现卡顿、数据异常、崩溃、未响应等问题。工作中也遇到了不少类似的问题,所以在此总结一下这类问题的几种解决思路。
案例
假设有一个App,有四个A控件,其中必须且只有一个为选中状态。而在另一个B控件中,需要实时显示并修改选中控件关联的一些参数信息,而这些参数信息需要从内存中读取。假设每次切换选中状态后读取与修改数据共需要200ms,更新UI需要100ms,总耗时300ms。
分析
关于上述案例,如果按照正常手段去处理,大家一定会想到对每一个A控件都添加点击事件,点击事件中进行数据的查询与UI的更新。然后随便点两下,功能OK,然后就完工了。然而,如果这时候快速的来回切换A控件的选中状态(两次点击间隔都在300ms以内)的话,由于每一次的查询与更新UI都需要300ms,而切换频率大于这个时间,这时候B控件的更新就显得“力不从心”,这时候就会出现卡顿甚至ANR。这样的问题在工作中很常见,怎么解决呢?这时候一般就会想到使用线程,将耗时操作统统放到线程中去,也就是把案例中的数据读取与修改数据的操作放到线程中去并发执行,读取与修改结束后,再通知主线程去更新UI。这样的做法使耗时操作在子线程中进行,减少了UI卡顿的时间,并且多线程并发查询,也大大提升了频繁查询数据时的速度。确实大大优化了App的性能,案例中的App在这种情况下,点击的间隔可以缩短到100ms(每次更新UI所用时间)而很流畅。然而,这个时候就会出现另一个问