我有这样的调用:
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());