假如连续屡次点击按钮会造成打开多个重复页面,或者者屡次请求,造成数据混乱。所以很多时候,我们需要避免这种情况发生。下面就通过AOP来实现这个功能。
/** * 防止按钮2连续屡次点击 * Created by zhouxu on 2018/9/17. */public class NoDoubleClickUtils { private final static int SPACE_TIME = 500;//2次点击的间隔时间,单位ms private static long lastClickTime; public synchronized static boolean isDoubleClick() { long currentTime = System.currentTimeMillis(); boolean isClick; if (currentTime - lastClickTime > SPACE_TIME) { isClick = false; } else { isClick = true; } lastClickTime = currentTime; return isClick; }}
@Aspectpublic 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(); } }}
@Aspect
:表示这是一个切面类
@Around
:环绕通知,会阻拦原方法内容的执行,也就是说会阻拦Activity中的onclick(),只执行AspectTest的onClickLitener()
proceedingJoinPoint.proceed();
:表示这个方法执行完毕了,可以放开阻拦了,接下来就会执行Activity中的onclick()
。
"execution(* android.view.View.OnClickListener.onClick(..))"
:表示切点,也就是说所有的点击事件,都会执行这个方法。
public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.button1).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.e(TAG, "button1 onClick: "); } }); }
连续点击的运行结果
可以看出在Activity的onclick处只执行了一次,也就是说通过AOP这种方式,在不侵入原有代码的情况下,就实现了防止连续点击的功能。
这种情况,就需要自己设置Pointcuts了。
1、自己设置注解接口
/** * 自己设置Pointcuts * Created by zhouxu on 2018/9/17. */@Retention(RetentionPolicy.CLASS)@Target({ElementType.CONSTRUCTOR, ElementType.METHOD})public @interface DoubleClick {}
2、解决切面的类AspectTest
@Aspectpublic class AspectTest { final String TAG = AspectTest.class.getSimpleName(); private boolean isDoubleClick = false; @Before("execution(@com.zx.aopdemo.DoubleClick * *(..))") public void beforeEnableDoubleClcik(JoinPoint joinPoint) throws Throwable { Log.e(TAG, "beforeEnableDoubleClcik: "); isDoubleClick = true; } @Around("execution(* android.view.View.OnClickListener.onClick(..))") public void onClickLitener(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { Log.e(TAG, "OnClick");// if (!NoDoubleClickUtils.isDoubleClick()) {// proceedingJoinPoint.proceed();// } if (isDoubleClick || !NoDoubleClickUtils.isDoubleClick()) { proceedingJoinPoint.proceed(); isDoubleClick = false; } }}
3、在Activity中允许点击的onclick前加一个@DoubleClick
的注解就好
public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); testAOP(); findViewById(R.id.button1).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.e(TAG, "button1 onClick: "); } }); findViewById(R.id.button2).setOnClickListener(new View.OnClickListener() { @DoubleClick @Override public void onClick(View v) { //允许连续点击 Log.e(TAG, "button2 onClick: "); } }); }}
连续点击button2的运行结果
可以发现button1是不能连续点击的,而加了@DoubleClick
注解的button2是可以连续点击的
参考文章:AOP在Android中的应用-过滤重复点击