[英]Still getting an IllegalStateException when using Google's People API despite subscribing on another thread using RxJava
Note: I'm using Kotlin along with RxKotlin for the useful extension functions. 注意:我正在将Kotlin和RxKotlin一起用于有用的扩展功能。
I'm trying to get some user data using Google's People API, and I just migrated all my AsyncTasks and stuff to using RxJava. 我试图使用Google的People API获取一些用户数据,而我只是将所有AsyncTasks和其他内容迁移到了RxJava。 Everything is working except for this part:
除此部分外,其他所有东西都在工作:
private fun getGooglePerson(service: PeopleService?, account: GoogleSignInAccount) =
Single.just(service?.people()
?.get("people/me")
?.setPersonFields("emailAddresses,birthdays,genders,phoneNumbers")
?.execute() ?: Person()) // If null, return an empty person (shouldn't ever be null, though)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeBy(
onError = {/*Do something*/},
onSuccess = {/*Do something*/}
)
Specifically, I'm getting an IllegalStateException
with the message, Calling this from your main thread can lead to deadlock
. 具体来说,我收到一条带有消息的
IllegalStateException
, Calling this from your main thread can lead to deadlock
。 I'm confused because I was under the impression that calling subscribeOn
should shift everything both above and below it (unless an observeOn
follows it) to another thread (in this case, Schedulers.io()
) I tried rewriting the code like so: 我很困惑,因为我觉得调用
subscribeOn
应该将其上方和下方的所有内容(除非observeOn
跟随它)都移动到另一个线程(在本例中为Schedulers.io()
),我试图像这样重写代码:
private fun getGooglePerson(service: PeopleService?, account: GoogleSignInAccount) =
service?.people()
?.get("people/me")
?.setPersonFields("emailAddresses,birthdays,genders,phoneNumbers")
?.execute() ?: Person() // If null, return an empty person (shouldn't ever be null, though)
.toSingle()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeBy(
onError = {/*Do something*/},
onSuccess = {/*Do something*/}
)
Still, no dice. 不过,没有骰子。 I'm completely stumped;
我完全陷入了困境。 what should I do?
我该怎么办? Where should I put that call to
execute()
so that it runs on a different thread? 我应该在哪里将调用放在
execute()
以便它在不同的线程上运行? Am I missing something? 我想念什么吗?
Let's break this down a little. 让我们分解一下。
Single.just(service?.people()
?.get("people/me")
?.setPersonFields("emailAddresses,birthdays,genders,phoneNumbers")
?.execute() ?: Person())
.subscribeOn(Schedulers.io())
We're starting with a Single.just(someValue)
. 我们从
Single.just(someValue)
。 We could rewrite your code like so, and it would be technically identical to what you wrote: 我们可以这样重写您的代码,并且从技术上讲,它与您编写的内容相同:
val person = service?.people()
?.get("people/me")
?.setPersonFields("emailAddresses,birthdays,genders,phoneNumbers")
?.execute() ?: Person())
Single.just(person)
Do you see the problem? 看到问题了吗? The service call is executed first in order to provide a value to the
Single.just
call. 首先执行服务调用,以便为
Single.just
调用提供值。
In order to run your service call once the rest of the chain has been setup (ie, upon subscription), you can use defer
: 为了在链的其余部分设置好后(即,在订阅时)运行服务调用,可以使用
defer
:
Single.defer(() -> service?.people()
?.get("people/me")
?.setPersonFields("emailAddresses,birthdays,genders,phoneNumbers")
?.execute() ?: Person())
.subscribeOn(Schedulers.io())
(syntax may be off, I don't have an IDE handy) (语法可能已关闭,我没有IDE可用)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.