K.O*_*.Os 0 android kotlin rx-java rx-java2
我在从主题获取最后发出的值时遇到问题
这是我的班级,负责发射和观察电池变化:
class BatteryLevelProvider @Inject constructor(
app: App
) {
private val context: Context = app
private val receiver: PowerConnectionReceiver = PowerConnectionReceiver()
init {
initializeReceiver()
}
private fun initializeReceiver() {
IntentFilter(Intent.ACTION_BATTERY_CHANGED).let { intentFilter ->
context.registerReceiver(receiver, intentFilter)
}
}
companion object {
val batteryLevelSubject = PublishSubject.create<Int>()
}
fun observeBatteryLevel(): Observable<Int> = batteryLevelSubject.distinctUntilChanged()
fun getCurrentBatteryLevel(): Int {
Timber.d("getCurrentBatteryLevel: ENTERED")
val blockingLast = batteryLevelSubject.blockingLast(0)
Timber.d("getCurrentBatteryLevel: $blockingLast")
return blockingLast
}
inner class PowerConnectionReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val level: Int = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1)
val scale: Int = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1)
val percentage= (level / scale.toFloat() * 100).toInt()
batteryLevelSubject.onNext(percentage)
Timber.d("Battery changed: $percentage")
}
}
}
Run Code Online (Sandbox Code Playgroud)
当我调用 getCurrentBatteryLevel() 时,它到达了 blocksLast 永远不会返回值并挂起应用程序。这是什么原因以及如何正确处理?
subject.blockingLast(0) 意思如下:在流完成发射值后获取最后一个值,如果它完成后没有发射任何值,则返回默认值。
这意味着blockingLast它将等到它接收到onComplete事件,因为只有这样它才能确定流已经结束(并发出最后一个值)。PublishSubject创建一个无限流,您永远不会batteryLevelSubject.onComplete手动结束流,这就是它永远挂起的原因。
您可以通过更改PublishSubject为轻松解决该问题BehaviorSubject。它们之间的主要区别在于BehaviorSubject缓存最后接收到的值,然后任何人都可以接收到该值。此外,您需要更改batteryLevelSubject.blockingLast(0)为batteryLevelSubject.value获取最后一个缓存的值(它不会阻止任何内容!)。但请注意,当您尚未放置任何内容时,该值在第一次运行时可能为空。您可以通过BehaviorSubject像这样创建默认值来轻松解决这个问题:
val subject = BehaviorSubject.createDefault(0)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
596 次 |
| 最近记录: |