避免 Thread.sleep 使用 RxJava

Avoid Thread.sleep using RxJava

我对这个方法应用了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)
}

因为你想做一个异步方法执行。您应该考虑使用 Observable.fromCallable() 而不是 Observable.just()。

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

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

只是 return 像这样的布尔值:

//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))

您的代码存在多个问题。你最好只使用像 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,这实际上违背了使用应该 "push" 对您进行更改的广播接收器的全部目的,而不是 "pulling"他们每秒。

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