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
相关产品推荐
相关产品推荐

