代码之家  ›  专栏  ›  技术社区  ›  K.Os

PublishSubject blockingLast()挂起Android应用程序,不调用

  •  0
  • K.Os  · 技术社区  · 7 年前

    我在获取主体最后发出的值时遇到问题

    这是我的课程,负责发射和观察电池变化:

    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")
        }
      }
    
    }
    

    它到达了blockingLast从未得到返回值并挂起应用程序。 原因是什么?如何妥善处理?

    1 回复  |  直到 7 年前
        1
  •  6
  •   Dmitry    7 年前

    subject.blockingLast(0) 表示以下内容:在流完成发出值之后获取最后一个值,如果流完成而没有发出任何值,则返回默认值。

    这意味着 blockingLast 将等到它收到 onComplete 事件,因为只有这样它才能确定流已经结束(并发出最后一个值)。 PublishSubject 无限流 你从不打电话 batteryLevelSubject.onComplete

    出版主题 BehaviorSubject . 它们之间的主要区别在于 行为主体 缓存最后接收的值,然后任何人都可以接收该值。而且,你需要改变 batteryLevelSubject.blockingLast(0) batteryLevelSubject.value 获取最后一个缓存的值(它不会阻止任何东西!)。但是请注意,在第一次运行时,如果还没有放入任何内容,则该值可能为null。你可以通过创建 行为主体 默认值如下:

    val subject = BehaviorSubject.createDefault(0)