使用AspectJ 处理Android二次点击

351 阅读1分钟

1,引入AspectJ

Android AspectJ简单使用

2,分析

点击事件都是由View.setOnClickListener触发

如果能在OnClickListener.onClick执行的时候进行判断,现在的点击比上一次的点击要大于一定的时间才能执行

long mLastClickTime;//记录上一次点击的时间
int DELAY=300;//设定每次点击的间隔必须要大于300毫秒 不然视为一次点击
setOnClickListener(new OnClickListener(View view){
        long now = System.currentTimeMillis();//获取当前点击的时间
        long timeOffset = now - mLastClickTime;//计算出两次点击的间隔时间
        
        if (timeOffset < 0) {//避免修改手机时间造成的错误
            mLastClickTime = 0;
            timeOffset = now;
        }
        if (timeOffset > DELAY) {
            mLastClickTime = now;
            // todo xx 这里开始执行判断逻辑
            
            
        }
    

});

3,问题

  1. 需要在每一次setOnClickListener方法中重写判断代码,造成大量的代码冗余
  2. 如果自定义OnClickListener可以实现,但项目如果已经存会存在修改量大的问题

4,AspecJ


@AspectJ
public class DemoInject{
    long mLastClickTime;//记录上一次点击的时间
    int DELAY=300;//设定每次点击的间隔必须要大于300毫秒 不然视为一次点击
    
    //重写匹配到实现OnClickListener的onClick方法
    @Around("execution(* android.view.View.OnClickListener.onClick(android.view.View))")
    public void reWriteOnClick(ProceedingJoinPoint joinPoint){
        long now = System.currentTimeMillis();
        long timeOffset = now - mLastClickTime;
        // 用户修改系统时间后,如果时间改小了,差值为负数,此时将timeOffset的值重置即可
        if (timeOffset < 0) {
            mLastClickTime = 0;
            timeOffset = now;
        }
        if (timeOffset > DELAY) {
            mLastClickTime = now;
            try {
                joinPoint.proceed();//继续执行之前的代码
            } catch (Throwable throwable) {
                throwable.printStackTrace();
            }
        }
        //如果这一次的点击和上一次间隔小于设定的时间,即为无效点击


    }
}

5,点击run 运行即可

注意:如果setOnClickListener传入的是lambedar表达式,可能会造成AspectJ重写无效,不知道版本足够高的AspectJ有没有解决这个问题