安卓开发封装处理Retrofit协程请求中的异常

上篇文章讲解了怎么使用 Kotlin的协程配合 Retrofit发起网络请求,使用也是非常方便,但是在处理请求异常还不是很人性化。这篇文章,我们将处理异常的代码进行封装,以便对异常情况返回给页面,提供更加友好的提示。

我们写一个扩展(全局)方法,就叫 ViewModelExt.kt,在下面创建方法。

/**
 * ViewModel扩展方法:启动协程
 * @param block 协程逻辑
 * @param onError 错误回调方法
 * @param onComplete 完成回调方法
 */
fun ViewModel.launch(
    block: suspend CoroutineScope.() -> Unit,
    onError: (e: Throwable) -> Unit = { _: Throwable -> },
    onComplete: () -> Unit = {}
) {
    viewModelScope.launch(
        CoroutineExceptionHandler { _, throwable ->
            run {
                // 这里统一处理错误
                ExceptionUtil.catchException(throwable)
                onError(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 = RetrofitClient.userService.login(user)
    if (resultData.code == 20000) {
        userInfo.value = RetrofitClient.userService.getUserInfo().data
    }
},onError = { e: Throwable ->

})

如果是返回的结果不对,可以这样做

fun login(user: User) = launch({
    val resultData = RetrofitClient.userService.login(user)
    if (resultData.code == 20000) {
        userInfo.value = RetrofitClient.userService.getUserInfo().data
    } else {
        throw ApiException(-1, "返回结果出错")
    }
},onError = { e: Throwable ->

})

ApiException是自定义的异常处理

Original: https://www.cnblogs.com/sw-code/p/15591713.html
Author: sw-code
Title: 安卓开发封装处理Retrofit协程请求中的异常

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/585576/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • POJ1475(Pushing Boxes)–bbffss

    假设只有一个箱子。游戏在一个R行C列的由单位格子组成的区域中进行,每一步, 你可以移动到相邻的四个格子中的一个,前提是那个格子是空的;或者,如果你在箱子旁边,你也可以推动箱子前进一…

    Linux 2023年6月7日
    0108
  • 【Python】**kwargs和takes 1 positional argument but 2 were given

    Python的函数定义中可以在参数里添加kwargs——简单来说目的是允许 添加不定参数名称的参数,并作为 字典传递参数。但前提是——你必须提供 参数名**。 例如下述情况: 1 …

    Linux 2023年6月13日
    0111
  • CentOS7安装部署Zabbix监控服务

    Zabbix Server通过Agent传来的数据写入数据库(MySQL),最终通过PHP+Apache在Web界面进行前端展示所以在启动Zabbix之前需要搭建LAMP环境 1、…

    Linux 2023年5月27日
    0119
  • 常用命令记录

    npm仓库查看和修改 npm config set registry https://registry.npm.taobao.org #设置使用淘宝提供的npm仓库 npm con…

    Linux 2023年5月27日
    083
  • MySQL — 数据操作语言

    DML 全称 Data Manipulation Language。数据操作语言,用来对数据库表中的数据进行增删改。 插入一条数据 插入多条数据 update &#x886…

    Linux 2023年6月8日
    0106
  • 如何隐藏shell脚本内容

    从事 Linux 开发的同学,经常需要编写 shell 脚本,有时脚本中会涉及到一些敏感内容,比如一些 IP 地址,用户名以及密码等,或者脚本中有一些关键的代码, 所有这些内容你都…

    Linux 2023年6月13日
    098
  • Pycharm快捷键设置(鼠标滚动控制字体大小)

    一、pycharm字体放大的设置 File —> setting —> Keymap —>在搜寻框中输入:increase —> Increase Font…

    Linux 2023年6月8日
    0106
  • Docker安装mysqli扩展和gd扩展

    Docker安装mysqli扩展 官方php镜像 docker exec -it php-fpm bash cd /usr/local/bin ./docker-php-ext-i…

    Linux 2023年6月13日
    068
  • 一文搞懂 Redis 架构演化之路

    作者:ryetan,腾讯 CSIG 后台开发工程师 现如今 Redis 变得越来越流行,几乎在很多项目中都要被用到,不知道你在使用 Redis 时,有没有思考过,Redis 到底是…

    Linux 2023年5月28日
    0104
  • K8S-kubeadm安装

    K8S-kubeadmin快速安装K8S集群 1.IP规划 节点 IP 组件 MASTER01(4C/6G,cpu核心数大于2) 192.168.80.20 docker、kube…

    Linux 2023年6月13日
    0106
  • 积分排名查看

    1年05个月 2018-9-17 1年04个月 2018-9-04 1年04个月 2018-8-23 1年04个月 2018-8-21 posted @2018-08-21 21:…

    Linux 2023年6月7日
    097
  • Cisco实验:【DHCP配置】客户端跨网段通过DHCP服务器自动获取动态IP和固定IP地址

    模拟环境:R1为路由器e0/0接口和e0/1接口分别连接两个网段,e0/0连接用户区域,e0/1连接服务器区域;用户区域中SW1为接入层交换机,连接一台PC(R2模拟)和一台打印机…

    Linux 2023年6月8日
    0191
  • centos 8及以上安装mysql 8.0

    本文适用于centos 8及以上安装mysql 8.0,整体耗时20分钟内,不需要FQ 1.环境先搞好 systemctl stop firewalld //关闭防火墙 syste…

    Linux 2023年6月7日
    0110
  • algorithm 头文件参考

    定义执行算法的 C++ 标准库容器模板函数。 该 <algorithm></algorithm> 库还使用该 #include <initialize…

    Linux 2023年6月7日
    0116
  • Java50个关键字之static

    关键字static主要有两种作用:第一,为某特定数据类型或对象分配单一的存储空间,而与创建对象的个数无关。第二,希望某个方法或属性与类而不是对象关联在一起,也就是说,在不创建对象的…

    Linux 2023年6月7日
    099
  • 介绍一种使用poweshell 监控的方式

    本篇将使用PowerShell脚本对SQL Server 的关键指标进行监控. 以下,用数据库空间容量为例,实现一下逻辑: 一、建表 为每台服务器创建一个表,用于记录服务器各个数据…

    Linux 2023年5月28日
    0102
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球