上篇文章講解了怎么使用Kotlin的協程配合Retrofit發起網路請求,使用也是非常方便,但是在處理請求例外還不是很人性化,這篇文章,我們將處理例外的代碼進行封裝,以便對例外情況回傳給頁面,提供更加友好的提示,
撰寫拓展方法
我們寫一個擴展(全域)方法,就叫ViewModelExt.kt,在下面創建方法,
/**
* ViewModel擴展方法:啟動協程
* @param block 協程邏輯
* @param one rror 錯誤回呼方法
* @param onComplete 完成回呼方法
*/
fun ViewModel.launch(
block: suspend CoroutineScope.() -> Unit,
one rror: (e: Throwable) -> Unit = { _: Throwable -> },
onComplete: () -> Unit = {}
) {
viewModelScope.launch(
CoroutineExceptionHandler { _, throwable ->
run {
// 這里統一處理錯誤
ExceptionUtil.catchException(throwable)
one rror(throwable)
}
}
) {
try {
block.invoke(this)
} finally {
onComplete()
}
}
}
統一例外處理
拓展方法里面對寫成程序做了統一攔截,在onComplete方法可以做統一的例外處理
/**
* 例外工具類
* @author ssq
*/
object ExceptionUtil {
/**
* 處理例外,toast提示錯誤資訊
*/
fun catchException(e: Throwable) {
e.printStackTrace()
when (e) {
is HttpException -> {
catchHttpException(e.code())
}
is SocketTimeoutException -> {
showToast(R.string.common_error_net_time_out)
}
is UnknownHostException, is NetworkErrorException -> {
showToast(R.string.common_error_net)
}
is MalformedJsonException, is JsonSyntaxException -> {
showToast(R.string.common_error_server_json)
}
is InterruptedIOException -> {
showToast("服務器連接失敗,請稍后重試")
}
// 自定義介面例外
is ApiException -> {
showToast(e.message?:"", e.code)
}
is ConnectException -> {
showToast( "連接服務器失敗" )
}
else -> {
showToast("${MyApplication.instance.getString(
R.string.common_error_do_something_fail
)}:${e::class.java.name}")
}
}
}
/**
* 處理網路例外
*/
fun catchHttpException(errorCode: Int) {
if (errorCode in 200 until 300) return// 成功code則不處理
showToast(
catchHttpExceptionCode(
errorCode
), errorCode
)
}
/**
* toast提示
*/
private fun showToast(@StringRes errorMsg: Int, errorCode: Int = -1) {
showToast(
MyApplication.instance.getString(
errorMsg
), errorCode
)
}
/**
* toast提示
*/
private fun showToast(errorMsg: String, errorCode: Int = -1) {
if (errorCode == -1) {
ToastUtils.showShort(errorMsg)
} else {
ToastUtils.showShort("$errorCode:$errorMsg")
}
}
/**
* 處理網路例外
*/
private fun catchHttpExceptionCode(errorCode: Int): Int = when (errorCode) {
in 500..600 -> R.string.common_error_server
in 400 until 500 -> R.string.common_error_request
else -> R.string.common_error_request
}
}
ApiException是自定義的例外類
如何使用
我們在一個ViewModel中可以這樣使用
fun login(user: User) = launch({
val resultData = https://www.cnblogs.com/sw-code/p/RetrofitClient.userService.login(user)
if (resultData.code == 20000) {
userInfo.value = RetrofitClient.userService.getUserInfo().data
}
},onError = { e: Throwable ->
})
如果是回傳的結果不對,可以這樣做
fun login(user: User) = launch({
val resultData = https://www.cnblogs.com/sw-code/p/RetrofitClient.userService.login(user)
if (resultData.code == 20000) {
userInfo.value = RetrofitClient.userService.getUserInfo().data
} else {
throw ApiException(-1,"回傳結果出錯")
}
},onError = { e: Throwable ->
})
ApiException是自定義的例外處理
使用Demo:
上篇文章:使用Kotlin協程配合Retrofit發送請求
本文來自博客園,作者:sw-code,轉載請注明原文鏈接:https://www.cnblogs.com/sw-code/p/15591713.html
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/374475.html
標籤:Android
上一篇:CG Kit探索移動端高性能渲染
