【发布时间】:2018-05-15 14:32:47
【问题描述】:
我刚开始使用 Retrofit 和 Rx 并创建了一个微笑 API,使用了这样的 (Kodein) 配置:
bind<CallAdapter.Factory>() with singleton {
RxJava2CallAdapterFactory.create()
}
bind<RetrofitInterface>() with singleton {
val retrofit = Retrofit.Builder()
.client(instance())
.baseUrl(instance<String>("apiRoot"))
.addCallAdapterFactory(instance())
.addConverterFactory(instance())
.build()
retrofit.create(RetrofitInterface::class.java)
}
现在看来,当我调用由 Retrofit 创建的 API 方法时,它们会在当前线程上订阅,而不是在 .subscribeOn(someThread) 中设置的线程上订阅,就像我调用时一样:
registrationSession(mUserName, PublicKeyType.XXXX, TargetType.YYYY)
.subscribeOn(io.reactivex.schedulers.Schedulers.newThread())
...
.subscribe(
{
},
{ error ->
Log.e("Error", error.message)
}
)
registrationSession 提供的改造将立即在主线程上调用请求,而不是在我订阅时,这是我不期望的(但话又说回来 - 我只是从 Rx 开始,我可能错了)
如果您想知道registrationSession是如何定义的,它是一个简单的函数包装器:
@POST("registration/session")
fun registrationSession(
@Header(Constants.LB_DEVICEID_HEADER) deviceUuid: String,
@Body registrationSessionPost: RegistrationSessionPost
): Observable<Response>
那么我该怎么做才能让registrationSession 在不同的线程上运行呢?有什么办法吗?
【问题讨论】:
-
我不确定您所说的“立即,而不是在我订阅时”是什么意思。在您的方法返回 observable 后立即调用 subscribe。是什么让您认为代码不会立即执行?
-
我认为 registrationSession() 调用会返回一个 observable,它会在订阅时对 Schedulers.newThread() 执行底层远程调用,即使我像上面一样立即订阅。如果假设是错误的 - 我该怎么做才能让它在不同的线程上执行请求?
-
是的,它使用
subscribeOn方法中提供的调度程序运行。你真的确定它在主线程上运行吗?理论上,如果您删除subscribeOn行,它将在主线程中运行,如果您在那里进行网络连接,则会在错误日志中产生“NetworkOnMainThread”异常 -
我确定,因为...它给了我现在的“NetworkOnMainThread”!
-
lol 好的,你试过 io Scheduler
Schedulers.io()了吗?我在发布的代码中没有看到任何邪恶,我怀疑问题一定发生在其他地方