Android中如何在ViewModel里动态调用多API并统一管理LiveData
解决方案
一、统一API请求与LiveData动态处理方案
1. 定义统一数据结构
根据API响应结构创建通用数据类:
data class Product( val key: String, val value: String, // 其他共同字段 ) data class ProductResponse( val code: Int, val data: List<Product> // 其他共同响应字段 )
2. 封装Retrofit接口
创建支持动态分类参数的API接口:
interface ProductApi { @GET("api/products/{category_name}") suspend fun getProducts( @Path("category_name") category: String ): Response<ProductResponse> }
3. ViewModel实现统一请求逻辑
用单个函数处理所有分类请求,通过Map型LiveData区分不同RecyclerView的数据,彻底避免重复代码:
class ProductViewModel : ViewModel() { // 用Map存储各分类数据,key为分类名,value为对应产品列表 private val _productDataMap = MutableLiveData<MutableMap<String, List<Product>>>() val productDataMap: LiveData<MutableMap<String, List<Product>>> = _productDataMap init { // 初始化空Map _productDataMap.value = mutableMapOf() } // 通用请求函数,接收分类名即可触发对应API请求 fun callProductData(category: String) { viewModelScope.launch { try { val response = RetrofitInstance.api.getProducts(category) if (response.isSuccessful) { response.body()?.data?.let { products -> val currentMap = _productDataMap.value ?: mutableMapOf() currentMap[category] = products _productDataMap.postValue(currentMap) } } } catch (e: Exception) { // 处理网络异常、解析异常等 } } } }
后续所有分类(Mobile/Shirt/Shoes等)都可调用同一个callProductData函数,各RecyclerView只需监听Map中对应分类的数据即可。
二、Fragment日志无输出的修复方案
你的代码核心问题是观察者注册时机晚于数据发送时机,导致LiveData的更新事件无法被捕获,修复如下:
1. 调整代码执行顺序
先注册观察者,再触发API请求,确保能捕获所有数据更新:
// 先注册观察者,提前监听数据变化 viewModel.productDataMap.observe(viewLifecycleOwner) { dataMap -> // 取出对应分类的数据打印 dataMap[CATEGORY_MOBILE]?.forEach { data -> Log.e("ProductsList", "Key => ${data.key} --- Value => ${data.value}") } } // 再触发API请求(如果延迟不是必要逻辑可直接去掉delay) lifecycleScope.launch { delay(500) viewModel.callProductData(CATEGORY_MOBILE) }
2. 额外排查点
- 确认
CATEGORY_MOBILE的字符串值与API路径参数完全匹配(注意大小写、特殊字符等) - 检查ViewModel中
callProductData函数是否正确执行了postValue逻辑 - 验证Retrofit配置正常,能成功连接目标服务器
内容的提问来源于stack exchange,提问作者Zankoo koochik
相关产品推荐
相关产品推荐

