触发某个事件后会去调用Android framework的sendPermissionProtectedBroadcast函数,这个函数会发送指定广播出去,有权限的app都会接收这一条广播。
在做压力测试时,由于较长时间(60s)内频繁触发这个事件,然后在这60s内就发送了大量相同的广播,当测试停下来的时候,从日志中还能看到广播还在排队发送。所以怎么去限制这个广播的重复发送呢?
想法:我想的是当发送完一条广播后,如果10s内判断即将发送的广播Action如果和上一条一样,就不发送,这样就大大减少的发广播的次数。这样的话就需要记录上一条广播发送时间,然后在发下一跳广播的时候做计算。
private void sendPermissionProtectedBroadcast(Intent intent) {
if (mEventInstalledPackages.isEmpty()) {
return;
}
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
for (String packageName : mEventInstalledPackages) {
intent.setPackage(packageName);
mContext.sendBroadcast(intent);
}
}
1. 添加一个变量来记录上一次发送广播的时间,比如:
java
private long mLastBroadcastTime;
2. 在发送广播前判断,如果与上次发送时间间隔小于给定值(如10秒),则不发送:
java
long now = System.currentTimeMillis();
if (now - mLastBroadcastTime < 10 * 1000) {
return; // 不发送广播
}
mLastBroadcastTime = now; // 更新上次发送时间
3. 发送广播的代码可以改成这样:
java
private void sendPermissionProtectedBroadcast(Intent intent) {
if (shouldThrottleBroadcast()) {
return; // 不发送广播
}
// 发送广播逻辑...
mLastBroadcastTime = System.currentTimeMillis(); // 更新上次发送时间
}
private boolean shouldThrottleBroadcast() {
long now = System.currentTimeMillis();
return now - mLastBroadcastTime < 10 * 1000; // 10秒内
}
这样就可以限制10秒内不会发送重复的广播,达到节流的效果。10秒这个时间可以根据你的需要灵活调整。
这个思路就是通过记录上次发送广播的时间,在发送下一条广播前判断时间间隔,如果在给定阈值内就不发送,达到限制重复广播的目的。
你的想法是对的,需要保存上一条广播发送的时间,并在发送下一条广播前和当前时间进行比较。下面是一个实现的示例:
private static final int MIN_SEND_INTERVAL = 10000; // 最小发送间隔为 10s
private long lastSendTime = 0;
private String lastAction = null;
private void sendPermissionProtectedBroadcast(Intent intent) {
if (mEventInstalledPackages.isEmpty()) {
return;
}
// 如果和上一条广播是同一个,且距离上次发送时间还不到 MIN_SEND_INTERVAL ,那么不发送
String currentAction = intent.getAction();
long currentTime = System.currentTimeMillis();
if (lastAction != null && lastAction.equals(currentAction) && currentTime - lastSendTime < MIN_SEND_INTERVAL) {
return;
}
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
for (String packageName : mEventInstalledPackages) {
intent.setPackage(packageName);
mContext.sendBroadcast(intent);
}
// 保存当前广播信息
lastSendTime = currentTime;
lastAction = currentAction;
}
在发送下一条广播前,需要先判断上一条广播的 Action 是否和当前一致,如果不一致直接发送,如果一致再判断距离上一次发送的时间间隔是否满足最小发送间隔 MIN_SEND_INTERVAL,如果满足则发送,不满足则不发送。同时,每次发送广播后都需要记录下当前时间和当前 Action,以便和下一条广播做比较。