ThrottleUtil
用于保证某个操作在一定时间内只执行一次的工具。
java
package com.cashpro.kash.lending.loan.utils;
/**
* <pre>
* Created by zhuguohui
* Date: 2024/6/26
* Time: 13:43
* Desc:用于节流执行任务,限制任务执行的频次
* </pre>
*/
import android.os.Handler;
import java.util.HashMap;
import java.util.Map;
public class ThrottleUtil {
private static final Handler HANDLER = new Handler();
private static Map<String, Long> lastExecutionTimeMap = new HashMap<>();
private static Map<String, Runnable> runnableMap = new HashMap<>();
/**
* 执行节流操作,确保操作在连续触发后至少等待指定的时间间隔再执行。
*
* @param opName 要执行操作的名称
* @param intervalMillis 时间间隔,以毫秒为单位
* @param runnable 要执行的操作
*/
public static synchronized void executeThrottled(String opName, long intervalMillis, Runnable runnable) {
long currentTime = System.currentTimeMillis();
long lastExecutionTime = 0;
if (lastExecutionTimeMap.containsKey(opName)) {
Long aLong = lastExecutionTimeMap.get(opName);
if (aLong != null) {
lastExecutionTime = aLong;
}
}
// 如果距离上次执行已经超过指定时间间隔,则立即执行操作
if (currentTime - lastExecutionTime >= intervalMillis) {
runnable.run();
lastExecutionTime = currentTime;
lastExecutionTimeMap.put(opName, lastExecutionTime);
} else {
// 如果时间未到,则移除之前的Runnable并重新添加
Runnable throttleRunnable = runnableMap.get(opName);
if (throttleRunnable != null) {
HANDLER.removeCallbacks(throttleRunnable);
runnableMap.remove(opName);
}
throttleRunnable = () -> {
runnable.run();
long lastExecutionTime1 = System.currentTimeMillis();
lastExecutionTimeMap.put(opName, lastExecutionTime1);
runnableMap.remove(opName);
};
runnableMap.put(opName, throttleRunnable);
HANDLER.postDelayed(throttleRunnable, intervalMillis - (currentTime - lastExecutionTime));
}
}
// 工具类不需要实例化,所以构造器私有
private ThrottleUtil() {
// 阻止实例化
}
// 可以在Activity或Fragment的onDestroy()中调用此方法,以确保没有内存泄漏
public static void clearCallbacks(String... opNames) {
for (String opName : opNames) {
Runnable runnable = runnableMap.get(opName);
if (runnable != null) {
HANDLER.removeCallbacks(runnable);
}
runnableMap.remove(opName);
}
}
}
使用
如下使用,其中第一个参数是一个操作名称,每个界面的操作不能重复。否则可能被其他地方取消。
按时取消
在界面销毁的时候记得移除操作