尽管使用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方便)