我是 RX Java 新手。在使用 Retrofit 实现 Rx java 时,我发现我的 doOnError(){}
但是我想要 RX Java 的 doOnError() 应该返回 ErrorBase() -> 这是我的自定义类。而不是可扔的。
它将帮助我处理中央的错误。我将把可抛出对象传递给我处理自定义消息的 ErrorBase 类。
下面是doOnError()
。我想在哪里返回 ErrorBase 对象
apiInterface.getLoginDetails(auth)
.doOnNext {
//LoginResponse
}
doOnError{
return ErrorBase(throwable)
}
其他类的代码。
Api接口(interface)类
interface ApiInterface {
@POST("login")
fun getLoginDetails(@Header(Constants.AUTHORIZATION) auth: String): Observable<LoginResponseModel>
}
登录存储库
class LoginRepository @Inject constructor(private val apiInterface: ApiInterface,
val utils: Utils) {
fun getLoginDetails(auth: String): Observable<LoginResponseModel> {
return apiInterface.getLoginDetails(auth)
.doOnNext {
}
.doOnError {
//Right now having throw-able object
}
}
}
错误库
class ErrorBase(private val throwable: Throwable) {
private var message: String?
private var statusCode: Int
init {
statusCode = getStatusCode()
message = getMessage()
}
private fun getStatusCode(): Int {
if (throwable is HttpException) {
val exception = throwable
return exception.code()
}
return -1
}
private fun getMessage() =
when (throwable) {
is IOException -> "Something Went Wrong"
is UnknownHostException -> "No internet connectivity"
is SocketTimeoutException -> "Slow Internet connectivity"
else -> throwable.message
}
}
LoginvViewModel
class LoginViewModel @Inject constructor(
private val loginRepository: LoginRepository) : ViewModel() {
private val TAG = this.javaClass.name
private var loginResult: MutableLiveData<LoginResponseModel> = MutableLiveData()
private var loginError: MutableLiveData<String> = MutableLiveData()
private var loginLoader: MutableLiveData<Boolean> = MutableLiveData()
private lateinit var disposableObserver: DisposableObserver<LoginResponseModel>
fun loginResult(): LiveData<LoginResponseModel> {
return loginResult
}
fun loginError(): LiveData<String> {
return loginError
}
fun loginLoader(): LiveData<Boolean> {
return loginLoader
}
private fun getLoginData(auth: String) {
loginLoader.postValue(true)
initLoginObserver()
loginRepository.getLoginDetails(auth)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.debounce(400, MILLISECONDS)
.subscribe(disposableObserver)
}
private fun initLoginObserver() {
disposableObserver = object : DisposableObserver<LoginResponseModel>() {
override fun onComplete() {
}
override fun onNext(loginDetails: LoginResponseModel) {
loginResult.postValue(loginDetails)
loginLoader.postValue(false)
}
override fun onError(e: Throwable) {
loginError.postValue(e.message)
loginLoader.postValue(false)
}
}
}
fun disposeElements() {
if (null != disposableObserver && !disposableObserver.isDisposed) disposableObserver.dispose()
}
fun loginClicked() {
getLoginData("auth")
}}
最佳答案
首先,doOnError
并非旨在转换/返回某些数据,而是有助于处理日志记录等副作用。
第二件事,ErrorBase
与 LoginResponseModel
不太适合因为他们没有共同的 parent 。
因此,我建议您采用以下解决方案:
为您的响应创建一个基类:
sealed class LoginResponse { class Result( ..your data here.. ) : LoginResponse() class Error( ... ) : LoginResponse() }
使函数返回
LoginResponse
并进行以下更改:fun getLoginDetails(auth: String): Observable<LoginResponse> { return apiInterface.getLoginDetails(auth) .map { data -> LoginResponse.Result(data) } .onErrorReturn { throwable -> LoginResponse.Error(throwable) } }
现在两个结果都有一个共同的父结果,您可以使用
getLoginDetails
通过以下方式:fun doRequest() { loginRepository.getLoginDetails(auth) .subscribe { result -> when (result) { is LoginResponse.Result -> //do something with result is LoginResponse.Error -> //do something with error } } }
一些解释。
onErrorReturn
完全按照您的需要 - 返回您的自定义值,以防发生错误如果不添加
LoginResponse
你必须做Observable<Any>
这是松散类型的,并不能很好地描述您的界面。制作
LoginResponse
sealed 只允许检查 2 种情况:发出的数据是否为 Result
或Error
。否则,Kotlin 编译器会强制您添加额外的else
分支
更新如果您需要在多个地方做同样的事情,您可以这样做:
sealed class Response<T> {
data class Result<T>(val result: T) : Response<T>()
data class Error<T>(val throwable: Throwable) : Response<T>()
}
fun getLoginDetails(auth: String): Observable<Response<LoginResponseModel>> {
return apiInterface.getLoginDetails(auth)
.map<Response<LoginResponseModel>> { data -> Response.Result(data) }
.onErrorReturn { throwable -> LoginResponse.Error(throwable) }
}
..and somewhere in your code..
fun handleResponse(response: Response<LoginData>) {
when (response) {
is Response.Result -> response.result
is Response.Error -> response.throwable
}
}
关于android - 从 Rx java Android 的 onError() 返回自定义对象而不是可抛出对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50599152/