Kotlin Jetpack Compose首页API调用优化与加载指示器修复
优化多API调用逻辑并修复加载指示器问题
一、优化多API调用逻辑
1. 并发执行多个API请求
放弃串行调用oggetti和utenti接口,改用协程并发执行以减少总耗时。ViewModel中可通过async+awaitAll或Flow的combine操作符合并结果:
协程async实现并发:
class HomeViewModel(private val repository: HomeRepository) : ViewModel() { private val _uiState = MutableStateFlow<HomeUiState>(HomeUiState.Loading) val uiState: StateFlow<HomeUiState> = _uiState.asStateFlow() init { fetchData() } private fun fetchData() = viewModelScope.launch { val oggettiDeferred = async { repository.getOggetti() } val utentiDeferred = async { repository.getUtenti() } try { val oggetti = oggettiDeferred.await() val utenti = utentiDeferred.await() _uiState.value = HomeUiState.Success(oggetti, utenti) } catch (e: Exception) { _uiState.value = HomeUiState.Error(e.message ?: "加载失败") } } } // 定义统一UI状态密封类 sealed class HomeUiState { object Loading : HomeUiState() data class Success(val oggetti: List<Oggetto>, val utenti: List<Utente>) : HomeUiState() data class Error(val message: String) : HomeUiState() }
Flow combine实现(适配实时更新场景):
class HomeViewModel(private val repository: HomeRepository) : ViewModel() { val uiState: StateFlow<HomeUiState> = combine( repository.getOggettiFlow(), repository.getUtentiFlow() ) { oggettiResult, utentiResult -> when { oggettiResult is Result.Loading || utentiResult is Result.Loading -> HomeUiState.Loading oggettiResult is Result.Success && utentiResult is Result.Success -> HomeUiState.Success(oggettiResult.data, utentiResult.data) else -> HomeUiState.Error("部分数据加载失败") } }.stateIn( scope = viewModelScope, started = SharingStarted.WhileSubscribed(5000), initialValue = HomeUiState.Loading ) }
2. 增加本地缓存策略
用Room等工具对oggetti和utenti数据做本地缓存,首次加载后优先读取缓存,后台同步最新数据,提升重复打开页面的速度:
class HomeRepository(private val apiService: ApiService, private val dao: HomeDao) { suspend fun getOggetti(): List<Oggetto> { val cache = dao.getOggetti() return if (cache.isNotEmpty()) { viewModelScope.launch { val remoteData = apiService.getOggetti() dao.insertOggetti(remoteData) } cache } else { val remoteData = apiService.getOggetti() dao.insertOggetti(remoteData) remoteData } } }
3. 后端API合并(若可行)
如果能协调后端,将oggetti和utenti接口合并为一个,减少网络请求次数,从根源降低加载耗时。
二、修复加载指示器异常问题
加载指示器提前结束的核心原因是未统一管理所有API请求的加载状态,之前的实现可能仅监听单个请求状态,导致某个请求完成就关闭加载,其他请求仍在进行。
1. 统一UI状态管理
使用上述HomeUiState密封类,仅当所有请求完成(成功/失败)时,才切换出Loading状态。
2. Compose中正确响应状态
在Compose页面根据uiState渲染UI,确保加载指示器在所有请求完成前持续显示:
@Composable fun HomeScreen(viewModel: HomeViewModel = viewModel()) { val uiState by viewModel.uiState.collectAsStateWithLifecycle() when (uiState) { is HomeUiState.Loading -> { Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { CircularProgressIndicator() } } is HomeUiState.Success -> { val state = uiState as HomeUiState.Success HomeContent(oggetti = state.oggetti, utenti = state.utenti) } is HomeUiState.Error -> { val errorMessage = (uiState as HomeUiState.Error).message Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { Text(text = errorMessage) } } } }
3. 规避局部状态错误
不要为每个API请求单独设置加载状态,必须用统一状态标识所有请求的整体加载情况,确保所有请求完成后才隐藏加载指示器。
内容的提问来源于stack exchange,提问作者Edoardo
相关产品推荐
相关产品推荐

