广播接收器仅接收一次信息

时间:2018-07-04 09:58:59

标签: android kotlin

我有一个可以同时发送两个广播的服务。

val i = Intent(PlayerService.INTENT_ACTION)
i.putExtra(EVENT_EXTRAS, PlayerEvent.PLAYER_READY.ordinal)
i.putExtra(DURATION_EXTRAS, mp.duration) //some duration
sendBroadcast(i)

val i1 = Intent(PlayerService.INTENT_ACTION)
i1.putExtra(EVENT_EXTRAS, PlayerEvent.ON_SECOND_CHANGED.ordinal)
i1.putExtra(DURATION_EXTRAS, player.duration) //another duration
sendBroadcast(i1)

意图的动作是相同的,但附加功能是不同的。最后,我只能从第二次广播中得到答案。谁知道原因是什么?

我的接收器实时数据:

class PlayerLiveEvent(val context: Context) : LiveData<Intent>() {

override fun onActive() {
    super.onActive()
    context.registerReceiver(receiver, IntentFilter(PlayerService.INTENT_ACTION))
}

override fun onInactive() {
    super.onInactive()
    context.unregisterReceiver(receiver)
}

private val receiver = object : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        postValue(intent)
    }
  }
}

观察这些事件的片段:

PlayerLiveEvent(activity!!).observe(this, Observer {
        it?.apply {
            val event = PlayerEvent.values()[getIntExtra(EVENT_EXTRAS, 0)]
            when (event) {
                PlayerEvent.PLAYER_READY -> {
                    println("PLAYER_READY")
                }
                PlayerEvent.ON_SECOND_CHANGED -> {
                    println("ON_SECOND_CHANGED")
                }
                else -> println()
            }
        }
    })

2 个答案:

答案 0 :(得分:1)

在主线程上执行第一个onReceive中的postValue任务之前调用第二个onReceive,因此将忽略第二次设置的值。您还可以从postValue的实现中看到这一点:

    ...
    synchronized (mDataLock) {
        // for your second call this will be false as there's a pending value
        postTask = mPendingData == NOT_SET;
        mPendingData = value;
    }
    // so this is true and so the method returns prematurely
    if (!postTask) {
        return;
    }
    ...

因此,请使用setValue,因为它会立即设置值并从主线程调用。

答案 1 :(得分:0)

问题出在LiveData中,事件没有按需传输。

document解释了为什么postValue仅发布一次。因此,解决方案如下:

private val receiver = object : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        value = intent
    }
}