You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin Android中Retrofit响应封装类类型参数报错问题

Retrofit响应封装类类型检查错误解决

问题描述

封装Retrofit响应的NetworkResult密封类时,ViewModel中用when判断NetworkResult.Success/Error/Loading完全正常,但在Fragment中观察对应LiveData时,编译器抛出错误:

需要一个类型参数。如果不想传递类型参数,请使用'Success<*>'

核心原因

NetworkResult的内部类Success/Error/Loading都声明了独立泛型<T>,在进行is类型检查时,Kotlin编译器无法自动推断泛型类型,必须显式指定参数——要么明确具体类型,要么用通配符*表示任意类型。

解决方案

方案1:用通配符*适配任意类型

在Fragment的when表达式中,给每个子类添加通配符*即可通过编译:

viewModel.saveGame.observe(viewLifecycleOwner) {
    when (it) {
        is NetworkResult.Success<*> -> {
            // 处理成功逻辑,it.data类型为Any?
        }
        is NetworkResult.Error<*> -> {
            // 处理错误逻辑
        }
        is NetworkResult.Loading<*> -> {
            // 处理加载逻辑
        }
    }

    // 原有数据判断逻辑可保留
    if (it.data != null) {
        binding.tvSave.text = "Saved"
        binding.ivSave.setColorFilter(
            ContextCompat.getColor(
                requireContext(),
                R.color.red
            )
        )
    } else {
        Log.d(TAG, "${it.message}")
    }
}

方案2:明确指定具体泛型类型

由于LiveData的泛型是NetworkResult<GameSaveSuccessResponse>,可以直接指定子类的泛型为GameSaveSuccessResponse,获得更精确的类型支持:

viewModel.saveGame.observe(viewLifecycleOwner) {
    when (it) {
        is NetworkResult.Success<GameSaveSuccessResponse> -> {
            // 此处it.data类型为GameSaveSuccessResponse,可直接使用
            binding.tvSave.text = "Saved"
            binding.ivSave.setColorFilter(
                ContextCompat.getColor(
                    requireContext(),
                    R.color.red
                )
            )
        }
        is NetworkResult.Error<GameSaveSuccessResponse> -> {
            Log.d(TAG, "${it.message}")
        }
        is NetworkResult.Loading<GameSaveSuccessResponse> -> {
            // 处理加载中状态,比如显示加载动画
        }
    }
}

内容的提问来源于stack exchange,提问作者oyeraghib

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 15:45:20