Klavor Lee
Life is just like a journey.

「安卓开发」Android防暴力点击事件处理解决方法及其存在的问题

Android中防爆力点击很多App中都会用到,但是我看过几个项目中的源码,大部分都是使用的System.currentTimeMillis()来获取当前时间与上一次点击时间间隔来做防暴力点击处理。
但是问题来了,由于System.currentTimeMillis()获取的是系统时间,这个时间会根据手机设置的时间而变化,那么就会导致一种情况,即当用户点击了一个View后记录了上一次的点击时间戳,这时将时间往前调之后,下一次再点击时System.currentTimeMillis()获取到的时间戳是比上一次点击时间戳要小的,因此就会导致点击无响应的情况发生。虽然说,这种情况几乎不会发生,或者发生了影响也不会太大,但是既然是一个问题,并且可以找到其他解决的方法,那么为什么不使用更优的方式来计算处理点击事件的时间间隔呢。
如下的代码中使用到了几种计算点击事件时间间隔的方式:

package org.devlang.demo.click;

import android.os.SystemClock;
import android.util.Log;
import android.view.View;

import java.util.Calendar;

public abstract class OnThrottleClickListener implements View.OnClickListener {
private static final int THROTTLE_CLICK_GAP_TIME = 300;
private long preClickTime;

@Override
public void onClick(View view) {
// long currentTimeMillis = System.currentTimeMillis();
// long currentTimeMillis = Calendar.getInstance().getTimeInMillis();
long currentTimeMillis = SystemClock.uptimeMillis();
// long currentTimeMillis = SystemClock.elapsedRealtime();
if (currentTimeMillis - preClickTime > THROTTLE_CLICK_GAP_TIME) {
onThrottleClick(view);
preClickTime = currentTimeMillis;
Log.d("cmf", "perform");
} else {
Log.d("cmf", "break");
}
}

public abstract void onThrottleClick(View view);
}

  • System.currentTimeMillis() 系统时间,会根据手机系统中设置的时间改变;
  • Calendar.getInstance().getTimeInMillis() 这种方式是最low的。因为每次点击都会创建一个Calendar实例,在后端开发中,都是拒绝使用这个类的,因为效率会比较低。
  • SystemClock.uptimeMillis() 自开机后,经过的时间,不包括深度睡眠的时间。Looper中所使用的也是这个方法,对时间间隔的计算比较有保证。
  • SystemClock.elapsedRealtime() 自开机后,经过的时间,包括深度睡眠的时间。

这也是之前开发中遇到的问题,虽然影响不大,但也可以注意一下这个问题。

You may also like...

发表评论

电子邮件地址不会被公开。 必填项已用*标注