使用RxJava避免Thread.sleep

时间:2018-07-17 06:17:28

标签: android rx-android

我将observable应用于此方法,但是在调用此方法后,这表示主线程上的工作过多。感谢您的帮助

fun isBatteryHealthGood(): Observable<Boolean> {
        var count = 0
        intent = context.registerReceiver(broadCastReceiver, IntentFilter(Intent.ACTION_BATTERY_CHANGED))

    while (batteryStatus == null && count < maxCount) {
        Thread.sleep(1000)
        count++
    }
    return Observable.just(batteryStatus == BatteryManager.BATTERY_HEALTH_GOOD)
}

3 个答案:

答案 0 :(得分:2)

我的解决方案是通过使用interval operator来避免使用Thread.sleep() 我认为您可以在isBatteryHealthGood()中忽略可观察的内容。

只需返回布尔值,如下所示:

//a simple function works here, no need
fun isBatteryHealthGood(): Boolean {


    return batteryStatus == BatteryManager.BATTERY_HEALTH_GOOD
}

最后像这样订阅:

Observable.
            interval(1000, TimeUnit.MILLISECONDS)
            take(maxCount) //place max count here
            .map { _ -> isBatteryHealthGood() }
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.maintThread())
            .subscribe {
                batterystat ->
                //do what you need
            }

PS:您应该只注册一次接收器

intent = context.registerReceiver(broadCastReceiver, IntentFilter(Intent.ACTION_BATTERY_CHANGED))

答案 1 :(得分:1)

要执行异步方法。您应该考虑使用Observable.fromCallable()而不是Observable.just()。

此处是详细的文章https://medium.com/yammer-engineering/converting-callback-async-calls-to-rxjava-ebc68bde5831

答案 2 :(得分:1)

您的代码有多个问题。您最好只使用RxBroadcastReceiver之类的库,这样就可以编写:

fun isBatteryHealthGood(): Observable<Boolean> {
    return RxBroadcastReceivers
        .fromIntentFilter(context, IntentFilter(Intent.ACTION_BATTERY_CHANGED))
        .map {
            it.getIntExtra(BatteryManager.EXTRA_HEALTH, 0) == BatteryManager.BATTERY_HEALTH_GOOD
        }
}

一大好处是您无需自己注册广播接收器,也根本不需要处理广播,该逻辑包含在库中并通过可观察的流进行路由。

因此,不需要Thread.sleepObservable.timer,这实际上违反了使用广播接收机的全部目的,该广播接收机应该将更改“推”给您,而不是每次都“拉”它们第二。

最后,当您dispose()的结果isBatteryHealthGood()时,它将自动为您注销广播接收器。