尽管使用RxJava在另一个线程上订阅,但在使用Google的People API时仍然收到IllegalStateExceptionexception
注意:我使用Kotlin和RxKotlin来实现有用的扩展function。
我正在尝试使用Google的People API获取一些用户数据,并且将所有的AsyncTasks和东西都移植到了RxJava中。 一切工作除了这部分:
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*/} )
具体来说,我得到一个IllegalStateException
的消息, Calling this from your main thread can lead to deadlock
。 我感到困惑,因为我的印象是,调用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*/} )
不过,没有骰子。 我完全难倒了; 我该怎么办? 我应该在哪里调用execute()
以便在不同的线程上运行? 我错过了什么吗?
让我们稍微分解一下。
Single.just(service?.people() ?.get("people/me") ?.setPersonFields("emailAddresses,birthdays,genders,phoneNumbers") ?.execute() ?: Person()) .subscribeOn(Schedulers.io())
我们从Single.just(someValue)
。 我们可以像这样重写你的代码,这在技术上与你写的是一样的:
val person = service?.people() ?.get("people/me") ?.setPersonFields("emailAddresses,birthdays,genders,phoneNumbers") ?.execute() ?: Person()) Single.just(person)
你看到这个问题吗? 服务调用首先执行,以便为Single.just
调用提供一个值。
为了运行你的服务电话一旦链的其余部分已经建立(即订阅),你可以使用defer
:
Single.defer(() -> service?.people() ?.get("people/me") ?.setPersonFields("emailAddresses,birthdays,genders,phoneNumbers") ?.execute() ?: Person()) .subscribeOn(Schedulers.io())
(语法可能关闭,我没有IDE方便)