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

Android Studio中如何将API返回值正确传入ViewModel?

问题:ViewModel无法获取API返回的媒体数量正确值

当前项目混合使用Java与Kotlin,API返回的媒体数量数据流转路径为:API响应 → ApiMediaMaxCntInfo → MaxMediaCountInfo → Repo → ViewModel → UiMediaMaxCount → Fragment。实际API返回图片数2、视频数1,但ViewModel中无法获取到该正确值。


相关代码

1. API响应接收类(Java)

public class ApiMediaMaxCntInfo {
    @SerializedName("ImageCount")
    private int imageCount;

    @SerializedName("VideoCount")
    private int videoCount;

    public int getImageCount() { return imageCount; }

    public int getVideoCount() { return videoCount; }
}

2. 数据转换类(Java)

public class MaxMediaCountInfo {
    private int imageCount;

    private int videoCount;

    public MaxMediaCountInfo(@NonNull ApiMediaMaxCntInfo apiMediaMaxCntInfo) {
        imageCount = apiMediaMaxCntInfo.getImageCount();
        videoCount = apiMediaMaxCntInfo.getVideoCount();
    }

    public MaxMediaCountInfo() {
    
    }

    public int getImageCount() { return imageCount; }

    public int getVideoCount() { return videoCount; }
}

3. Repo层代码(Kotlin)

override fun getMediaMaxCountUC(context: Context): Flowable<UiResponse<MaxMediaCountInfo>> {
    return getUserInfoFromStorage(context).flatMap { userInfo ->
        siteSurveyRemoteResource.getMediaMaxCount(userInfo.userCredential.token)
            .map { apiResponse ->
                val cntInfo = MaxMediaCountInfo(apiResponse.data[0])
                UiResponseFactory.getSuccessUiResponse(cntInfo, apiResponse.message)
            }
    }
}

4. UI层数据类(Kotlin)

data class UiMediaMaxCount(
    val imageCount: Int = 0,
    val videoCount: Int = 0
)

5. ViewModel相关代码(Kotlin)

请求方法:

fun doCheckMediaMaxCount(): LiveData<Event<UiResponse<UiMediaMaxCount>>>{
        return RxHandleUtil.handleEventPublisherWithContentChange({
            surveySiteSurveyRepository.getMediaMaxCountUC(getApplication())
        }, { maxMediaCountInfo ->
            UiMediaMaxCount(
                maxMediaCountInfo.imageCount,
                maxMediaCountInfo.videoCount)
        })
    }

错误的初始化逻辑:

private val imageCnt = UiMediaMaxCount().imageCount
private val videoCnt = UiMediaMaxCount().videoCount
private val dataOverflow2 = imageCnt + videoCnt

6. Fragment触发请求代码(Kotlin)

private fun handleMaxMediaCountCheck() {
        processViewModel.doCheckMediaMaxCount().observe(viewLifecycleOwner, EventObserver { response->
            handleRxResponse(response, object : OnResponseListener<UiMediaMaxCount>(){

                override fun onServerFailResponse(message: String?) {
                    message?.let { it1 -> showError(it1) }
                }

                override fun onInvalidResponse(message: String?) {
                    message?.let { it1 -> showError (it1)  }
                }

                override fun onSuccessResponse(data: UiMediaMaxCount?, message: String?) {
                    data?.let {
                        maxPicCnt = data.imageCount
                        maxVideoCnt = data.videoCount
                    }
                }
            })
        })
    }

解决建议

  1. 修正ViewModel变量初始化逻辑
    当前直接通过UiMediaMaxCount()创建实例获取值,只会拿到默认的0,完全未关联API返回数据。需将变量改为可观察状态,用LiveData存储和计算:

    private val _mediaMaxCount = MutableLiveData<UiMediaMaxCount>()
    val mediaMaxCount: LiveData<UiMediaMaxCount> = _mediaMaxCount
    
    fun doCheckMediaMaxCount(): LiveData<Event<UiResponse<UiMediaMaxCount>>>{
        return RxHandleUtil.handleEventPublisherWithContentChange({
            surveySiteSurveyRepository.getMediaMaxCountUC(getApplication())
        }, { maxMediaCountInfo ->
            UiMediaMaxCount(
                maxMediaCountInfo.imageCount,
                maxMediaCountInfo.videoCount).also {
                    _mediaMaxCount.value = it // 保存API返回的真实数据
                }
        })
    }
    
    // 基于LiveData动态计算总数
    val dataOverflow2: LiveData<Int> = Transformations.map(mediaMaxCount) {
        it.imageCount + it.videoCount
    }
    
  2. 校验Repo层数据转换有效性
    确认apiResponse.data[0]是有效实例,避免数组越界或空数据问题,可添加日志排查:

    map { apiResponse ->
        Log.d("Repo", "API数据长度: ${apiResponse.data.size}")
        if (apiResponse.data.isNotEmpty()) {
            val apiInfo = apiResponse.data[0]
            Log.d("Repo", "图片数: ${apiInfo.getImageCount()}, 视频数: ${apiInfo.getVideoCount()}")
            val cntInfo = MaxMediaCountInfo(apiInfo)
            UiResponseFactory.getSuccessUiResponse(cntInfo, apiResponse.message)
        } else {
            UiResponseFactory.getFailUiResponse("无媒体数量数据")
        }
    }
    
  3. 验证Fragment接收数据正确性
    在Fragment的成功回调中打印数据,确认数据是否传递正常:

    override fun onSuccessResponse(data: UiMediaMaxCount?, message: String?) {
        data?.let {
            Log.d("Fragment", "接收图片数: ${it.imageCount}, 接收视频数: ${it.videoCount}")
            maxPicCnt = it.imageCount
            maxVideoCnt = it.videoCount
        }
    }
    
  4. 检查序列化字段匹配度
    确认API返回的字段名与ApiMediaMaxCntInfo中@SerializedName完全一致(包括大小写),避免因字段不匹配导致数据解析失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 06:15:17