AOP实现防止连续点击

防止连续点击的实现方式有很多种,比如,在所有的onclick里面加上防多次点击的代码,或者定义一个新的OnClickListener,在里面加上防多次点击的代码,然后项目中的所有OnClickListener都用这个listener,当然还有一些其他的方式,这里将介绍一种新的方式来实现,那就是aop。

不知道aop的可以看这篇文章深入理解Android之AOP

在android实现aop通常是用AspectJ来实现,AspectJ的用法可以看这篇文章AspectJ基本用法.

使用OnClickLitener的代码

public class MainActivity extends AppCompatActivity {
    final String TAG = MainActivity.class.getSimpleName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.text).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.e(TAG, "execute click");
            }
        });
    }
}

首先定义一个防止多次点击的工具类

public class NoDoubleClickUtils {
    private static long lastClickTime = 0;
    private final static int SPACE_TIME = 500;

    public synchronized static boolean isDoubleClick() {
        long currentTime = System.currentTimeMillis();
        boolean isClick2;
        if (currentTime - lastClickTime >
                SPACE_TIME) {
            isClick2 = false;
        } else {
            isClick2 = true;
        }
        lastClickTime = currentTime;
        return isClick2;
    }
}

然后使用AspectJ对OnclickLitener进行插桩,

@Aspect
public class AspectTest {
    final String TAG = AspectTest.class.getSimpleName();

    @Around("execution(* android.view.View.OnClickListener.onClick(..))")
    public void onClickLitener(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        Log.e(TAG, "OnClick");
        if (!NoDoubleClickUtils.isDoubleClick()) {
            proceedingJoinPoint.proceed();
        }
    }
}

运行程序,多次点击按钮后,log如下

04-03 19:41:20.043 5784-5784/ E/AspectTest: OnClick
04-03 19:41:20.043 5784-5784/ E/MainActivity: execute click
04-03 19:41:20.222 5784-5784/ E/AspectTest: OnClick
04-03 19:41:20.377 5784-5784/ E/AspectTest: OnClick
04-03 19:41:20.542 5784-5784/ E/AspectTest: OnClick
04-03 19:41:20.689 5784-5784/ E/AspectTest: OnClick
04-03 19:41:20.838 5784-5784/ E/AspectTest: OnClick
04-03 19:41:21.012 5784-5784/ E/AspectTest: OnClick
04-03 19:41:21.158 5784-5784/ E/AspectTest: OnClick

通过log可以看出onClickLitener执行了多次,但使用clcik的的地方只执行了一次。这样,就可以在不改变原来代码的情况下,实现防止连续点击的功能。

但是当又有需求:要求部分按钮是可以连续点击的,该怎么办能?这个时候只要加个注解文件就好。

首先定义个注解

@Retention(RetentionPolicy.CLASS)
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD})
public @interface DoubleClick {
}

并且修改之前的AspectTest文件

private boolean canDoubleClick = false;

@Before("@annotation(*..DoubleClick)")
public void beforeEnableDoubleClcik(JoinPoint joinPoint) throws Throwable {
    canDoubleClick = true;
}

@Around("execution(* android.view.View.OnClickListener.onClick(..))")
public void OnClickListener(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
    Log.e(TAG, "OnClick:");
    if (canDoubleClick || !NoDoubleClickUtils.isDoubleClick()) {
        proceedingJoinPoint.proceed();
        canDoubleClick = false;
    }
}

现在只要在可以连续点击的按钮的onclick前加一个@DoubleClick的注解就好,将MainActivty修改如下

public class MainActivity extends AppCompatActivity {
    final String TAG = MainActivity.class.getSimpleName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.text).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.e(TAG, "text execute click");
            }
        });

        findViewById(R.id.text2).setOnClickListener(new View.OnClickListener() {
            @DoubleClick
            @Override
            public void onClick(View v) {
                Log.e(TAG, "text2 execute click");
            }
        });
    }
}

运行程序,分别连续点击第一个view和第二个view,log如下

04-03 21:35:27.304 21347-21347/ E/AspectTest: OnClick:
04-03 21:35:27.304 21347-21347/ E/MainActivity: text execute click
04-03 21:35:27.464 21347-21347/ E/AspectTest: OnClick:
04-03 21:35:27.645 21347-21347/ E/AspectTest: OnClick:
04-03 21:35:27.776 21347-21347/ E/AspectTest: OnClick:
04-03 21:35:27.948 21347-21347/ E/AspectTest: OnClick:
04-03 21:35:28.104 21347-21347/ E/AspectTest: OnClick:
04-03 21:35:28.277 21347-21347/ E/AspectTest: OnClick:
04-03 21:35:28.441 21347-21347/ E/AspectTest: OnClick:
04-03 21:35:28.605 21347-21347/ E/AspectTest: OnClick:
04-03 21:35:28.770 21347-21347/ E/AspectTest: OnClick:
04-03 21:35:35.533 21347-21347/ E/AspectTest: OnClick:
04-03 21:35:35.533 21347-21347/ E/MainActivity: text2 execute click
04-03 21:35:35.715 21347-21347/ E/AspectTest: OnClick:
04-03 21:35:35.715 21347-21347/ E/MainActivity: text2 execute click
04-03 21:35:35.862 21347-21347/ E/AspectTest: OnClick:
04-03 21:35:35.862 21347-21347/ E/MainActivity: text2 execute click
04-03 21:35:36.026 21347-21347/ E/AspectTest: OnClick:
04-03 21:35:36.026 21347-21347/ E/MainActivity: text2 execute click
04-03 21:35:36.199 21347-21347/ E/AspectTest: OnClick:
04-03 21:35:36.199 21347-21347/ E/MainActivity: text2 execute click
04-03 21:35:36.355 21347-21347/ E/AspectTest: OnClick:
04-03 21:35:36.355 21347-21347/ E/MainActivity: text2 execute click
04-03 21:35:36.520 21347-21347/ E/AspectTest: OnClick:
04-03 21:35:36.520 21347-21347/ E/MainActivity: text2 execute click

可以发现第一个view不能被连续点击了,但第二个可以连续点击。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值