1,引入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,问题
- 需要在每一次setOnClickListener方法中重写判断代码,造成大量的代码冗余
- 如果自定义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有没有解决这个问题