安卓防止重复点击正确的解决方案

网上大多数的解决方案都是设置一个延迟时间,但是使用过的人都知道,这个方案其实并不怎么好用.而且从代码上讲,这也只是一个治现象而不治本的方案

在解决问题前需要先要知道 为什么会触发重复点击
先来个日志:

aa.gif

可以看到:
即使主线程处于阻塞状态,app依然可以接收到触摸事件,而重复点击的根源就来自于这里!!!

为什么会这样呢?因为,触摸事件的接收线程不在自己app的主线程,而在于其它的进程,即使app主线程阻塞,当阻塞完成时,依然会收到并处理其它进程发送过来的触摸事件,而重复点击就出现在阻塞的时候.

先补充一个知识点:


image.png

onClick事件并不是在触摸事件中执行的,而是被抛到messageQueue中执行的!!!

大致画下click1点击后的时间图:


微信截图_20201107233607.png

当搞清重复点击事件产生的原因后,解决方案就有了.
先上代码:


image.png

再上使用后的效果图:


bb.gif

原理就先不讲了,因为如果阻塞发生在当前点击事件中依然是有问题的,所以接下来讲更重要的问题.
先看bug图:


cc.gif

再上解决方案.其实再第一种解决方案中已经截出来了,就是注释的部分,但是我进一步测试后发现还是有bug,因为在下,下 次message执行前并不能保证系统已完全执行完所有阻塞的触摸事件,然后就只能祭出延时大法了,不过不需要使用夸张的几百ms,只需十几ms就可以了,比如我设置的16ms就基本上够用了,想必这也是一个非常好的值.
上代码,这次直接上同时控制两个控件组合的防重复点击

dd.gif

最后上解决方案的原理图:


微信截图_20201108012204.png

到这里,我们已经解决了一种情况的重复点击问题。
即:主线程阻塞引起的重复点击
当然还有一种重复点击问题,也是最重要的,就是activity多次被启动的问题。

这个问题在模拟器中测试不出来,接下来真机测试,然后依然是一段日志:


微信截图_20201108100332.png

以华为手机为例,当A activity->onPause,B activity ->onResume后,A activity居然还能接收到触摸事件!!!
这个时间段是很长的,而且当B activity接手触摸事件时,已经经历了多次的message的转换,根本无法在合适的时机进行拦截和取消拦截。

所以我只能对onPause下手了,当activity调用onPause后居然还能接收触摸事件这本来就很不合理。而且这样处理起来貌似也没有任何的问题,所以就有了下面的解决方案:


image.png

相信没有什么需求会是在activity调用onPause后依然接收触摸事件,如果有那就再加个延迟来解除拦截,此时就可以直接加给1000ms的延迟都是无所谓的。

你可能感兴趣的:(安卓防止重复点击正确的解决方案)