【发布时间】:2017-08-17 13:55:40
【问题描述】:
我正在使用retorift 访问getAricle api 并获取与用户相关的文章列表。如果传递的令牌过期,getArticle api 将抛出错误,如果是这样,我必须调用 refreshToken api 来获取新令牌,然后我必须再次调用 getArticle api
ApiController.createRx().getArticle(token)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ response -> toast(response.body().url) }, { e ->
println(e.printStackTrace())
if(e is HttpException && e.code() in arrayOf(401,403)){
//Here I want to call refresh tolken api
toast("Auth error")
}
else
toast(R.string.something_went_wrong)
})
编辑
尽管给出的答案显示了一些方向,但这些并不是我问题的直接答案。这就是解决它的方法,但我觉得这可以重构为更好的代码
ApiController.createRx().getArticle(Preference.getToken())
.flatMap { value ->
if (value.code() in arrayOf(403, 401)) {
ApiController.refreshToken()
ApiController.createRx().getArticle(Preference.getToken())
} else Observable.just(value)
}
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ response -> println("Success") }, { e ->
e.printStackTrace()
toast(R.string.something_went_wrong)
})
fun refreshToken() {
val token:String?=ApiController.createRx().refreshToken(Preferences.getRefreshToken()).blockingFirst()?.body()?.token
if (token != null) Preferences.setAuthToken(token)
}
编辑
我将代码重构为更简洁的版本
Observable.defer { ApiController.createRx().getArticle(Preferences.getToken()) }
.flatMap {
if (it.code() in arrayOf(401, 403)) {
ApiController.refreshToken()
Observable.error(Throwable())
} else Observable.just(it)
}
.retry(1)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({println("Success") }, {
it.printStackTrace()
toast(R.string.something_went_wrong)
})
fun refreshToken() {
var token: String? = null
try {
token = createRx().refreshToken(Preferences.getRefreshToken()).blockingFirst().body()!!.token
} catch (e: Exception) {
throw e
}
println("saving token")
if (token != null) Preferences.setAuthToken(token)
}
编辑
请查看我对最终重构代码的回答
【问题讨论】:
-
首先,通过改造,您可以避免直接访问
onError。您可以返回Single<Result<CustomObject>>,它永远不会返回错误。但是如果你想继续得到onError,请尝试使用RxJava的错误处理运算符here -
@masp 在这两种情况下,我都无法理解如何调用 getArticle api。你能告诉我怎么做吗
-
你能解决你的问题吗?提供的任何答案是否有帮助?如果是这样,请考虑投票任何有用的答案,如果其中一个让您找到解决方案,请接受该答案。
-
@theFunkyEngineer 嘿,我花了一些时间解决了这个问题,我把它写成答案请评论你的建议
标签: android rx-java retrofit2 rx-java2 rx-kotlin