Hook技术实现无侵入式解决按钮重复点击

一、前言

通常android系统需要做一些统一的处理,最简单的选择是在BaseActivity中,但是由于BaseActivity的
1,强侵入性(改变原有代码结构)
2,java的硬编码特性(在预编译阶段需要存在才能处理,但大部分源码sdk已经写死了不可能单独生成自己的一个sdk)
这样就使得AOP特别的火爆,这里以入门基础hook为知识点,以最简单的防抖处理为例实战一下。

java常用编程思想面向过程(POP)、面向对象(OOP)、面向接口(IOP)、面向切面(AOP)区别:

  • 面向过程:典型的是C/C++的结构体,结构体里只有变量,没有处理变量的方法,需要专门编写处理变量的方法。
  • 面向对象:ArrayList list=new ArrayList();坏处是如果改为LinkedList,所有代码可能需要重写,同时扩展一个新的List的话,需要重新调用。
  • 面向接口:List=new Arraylist();是面向对象的一种形式,广义上讲,抽象类也是接口的一种形式,使用该类的某种属性(接口)来表示,降低耦合性,增加代码复用性。
  • 面向切面:这种在运行时,动态地将代码切入到类的指定方法、指定位置上的编程思想就是面向切面的编程。

二、环境配置

首先我们需要配置SpringAOP的插件依赖,在项目根目录下配置插件版本,并且在需要依赖的module中依赖该插件,同时也要引入该jar包。

在这里插入图片描述
在这里插入图片描述

三、AOP代码实现

这里我们新建一个带插件注解的类作为aop的入口,然后在该类中声明具体的拦截器。从拦截器返回的连接点中取出我们的实例对象view,从而实现务无侵入式点击事件的拦截。

@Aspect
public class AspectDoubleClick {
    private long delayTime = 2000;
    private long lastTime; //上次间隔时间
    private View lastView; //点击的view

    @Around("execution(* android.view.View.OnClickListener.onClick(..))")
    public void onClickListener(ProceedingJoinPoint joinPoint) throws Throwable {
        //获取连接点方法运行时的入参列表(这里拦截的是触发增强动作的控件)
        Object[] args = joinPoint.getArgs();
        View view = (View) args[0];//这里取第一个即可
        if (view != lastView) { //不是同一个View直接过
            joinPoint.proceed();
            lastView = view;
            lastTime = System.currentTimeMillis();
            return;
        }
        if (System.currentTimeMillis() - lastTime >= delayTime) {
            joinPoint.proceed();
            lastTime = System.currentTimeMillis();
            lastView = view;
        }
    }
}

到此一个简单的防重复点击已经实现,可以算结束了,我们运行项目效果图如下

在这里插入图片描述

三、完美实现

但是这里统一拦截仍存在以下弊端 1,部分点击事件不需要拦截如何处理 2,部分点击事件需要延迟的与全局的2000ms不一样如何简单处理
3,部分activity中的页面都不需要拦截如何统一处理 4,绝大部分事件是带有状态的如何简单处理(比如登录了才能点击)
5,在统一拦截下,只有极少个点击事件需要特殊自定义的如何处理 那么后面可以参看这个详细版的,源代码注释明确

发布了58 篇原创文章 · 获赞 33 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/liuxingyuzaixian/article/details/104589863