广播延迟了

时间:2017-06-13 08:31:47

标签: android android-broadcastreceiver

我们使用广播来传达远程服务和UI之间的状态变化。这样做,我们发现了一个非常奇怪的行为:有时(我找不到任何线索,为什么)这些广播延迟了8s左右。

我们如何发送它们(非常基本,mState只是一个枚举)(服务中的远程进程):

Intent intent = new Intent();
intent.setAction(ACTION_STATE_CHANGED);
intent.putExtra(EXTRA_STATE, mState);

Service.get().sendBroadcast(intent, null);

静态接收器的注册方式(App):

<receiver android:name=".ServiceStateReceiver">
    <intent-filter>
        <action android:name="service.intent.action.STATE_CHANGE" />
    </intent-filter>
</receiver>

接收器类(App):

public class ServiceStateReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.v("State", "State via static received");
    }
}

现在有时会延迟(总是针对相同的状态)

州枚举:

public enum State {
    DISCONNECTED,
    BT_DISABLED,
    BT_SCANNING,
    BT_TIMEOUT,
    BT_FAILURE,
    BT_LOCATION_NEEDED,
    CONNECTING,
    ACTIVATION_FAILURE,
    VIN_NEEDED,
    CAR_MODEL_NEEDED,
    MILEAGE_NEEDED,
    READY,
    IGNITION_OFF,
    IGNITION_ON;

    @Override
    public String toString() {
        return name();
    }
}

现在出现了一个奇怪的部分:如果我注册一个动态接收器,我们总会立即收到所有广播。静态的还有那么大的延迟。如果我通过sendOrderedBroadcast发送广播(静态和动态)有这种延迟。

动态接收器:

registerReceiver(new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                Log.i("State", "State via dynamic received");
            }
        }, new IntentFilter(State.ACTION_STATE_CHANGED));

到目前为止我尝试了什么:

  • 从主线程/工作线程发送广播(没有更改)
  • 使用权限属性播放(未更改)
  • 连续多次发送广播(不改变任何内容,现在只获得多个延迟广播)

另外:没有看似相关的logcat输出。试用不同的设备(OnePlus 3 7.1.1,Z3 6.0.1,S7 Edge 7.1.1),都表现出相同的行为

我认为这可能是相关的:Android network state change detection takes time

1 个答案:

答案 0 :(得分:3)

在找了几个小时的答案后,我发现了?发布后的解决方案。

似乎向intent添加FLAG_RECEIVER_FOREGROUND标志会完全消除此延迟。如果这是一个很好的“修复”,或者如果我用它破坏其他东西,那么仍然很高兴知道为什么会发生这种情况。

这就是诀窍:

    intent.setFlags(FLAG_RECEIVER_FOREGROUND);
  

如果设置,则在发送广播时,允许收件人运行   前台优先级,具有较短的超时间隔。在正常期间   广播接收器不会自动悬挂出来   背景优先级。

来源: https://developer.android.com/reference/android/content/Intent.html#FLAG_RECEIVER_FOREGROUND