例外:阻止连接不能在UI线程上调用,尽管我在另一个线程上订阅



我有这样的调用:

 val connectionResult = googleApiClient.blockingConnect()

这是导致此异常的原因:

java.lang.IllegalStateException: blockingConnect 不得在 UI 线程上调用

at com.google.android.gms.common.internal.zzbp.zza(Unknown Source)
at com.google.android.gms.common.api.internal.zzbd.blockingConnect(Unknown Source)
at com.elstatgroup.elstat.NexoLocationManager.startLocationUpdatesGmsApi(NexoLocationManager.kt:510)
at com.elstatgroup.elstat.NexoLocationManager.startLocationUpdates(NexoLocationManager.kt:498)
at com.elstatgroup.elstat.NexoLocationManager.appendRSSIEvent(NexoLocationManager.kt:283)
at com.elstatgroup.elstat.NexoLocationManager.appendRSSIEvent(NexoLocationManager.kt:273)
at com.elstatgroup.elstat.NexoLocationTest.testAppendLocationEvents(NexoLocationTest.kt:111)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.robolectric.RobolectricTestRunner$HelperTestRunner$1.evaluate(RobolectricTestRunner.java:497)
at org.robolectric.internal.SandboxTestRunner$2.evaluate(SandboxTestRunner.java:228)
at org.robolectric.internal.SandboxTestRunner.runChild(SandboxTestRunner.java:110)
at org.robolectric.internal.SandboxTestRunner.runChild(SandboxTestRunner.java:37)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.robolectric.internal.SandboxTestRunner$1.evaluate(SandboxTestRunner.java:64)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

我想,这会有所帮助:

 Observable.just(googleApiClient.blockingConnect())
                    .subscribeOn(Schedulers.newThread())
                    .subscribe(Consumer { connectionResult ->
                        if (connectionResult.isSuccess()) {
                //do something
                     }
                    })

但我错了,这无济于事。我让它不崩溃的唯一方法是:

         Thread(Runnable {
                val connectionResult = googleApiClient.blockingConnect() 
                if (connectionResult.isSuccess()) {
                    //do something
                }
            }).start()

那么为什么我的RxJava解决方案不起作用呢?

Observable.just()接受传递给下一个链接可观察对象的值。如果你仔细检查,那么在你的情况下

这里
Observable.just(googleApiClient.blockingConnect())

googleApiClient.blockingConnect()首先执行just因为运算符需要一个值/值。所以这里需要一个接受函数调用或类似东西的运算符。

对于您的情况Observable.fromCallable()可以使用它接收可调用的参数:

Observable.fromCallable(() -> googleApiClient.blockingConnect());

在这里,googleApiClient.blockingConnect()将在您订阅可观察链时执行。

这是因为 Observable#just 很渴望并且会阻止直到 #blockingConnect 完成。

这个例子应该可以解决问题:

    Observable.fromCallable(() -> {
        return googleApiClient.blockingConnect();
    }).subscribeOn(Schedulers.io());

最新更新