Android Navigation Component返回时避免API重复调用与数据刷新方案咨询
解决方案
1. 在ViewModel中实现搜索结果缓存
核心问题是每次收到搜索Query时都会发起新的API请求,没有复用已有结果。在SearchViewModel中添加缓存逻辑,避免重复请求:
class SearchViewModel : ViewModel() { // 缓存不同搜索关键词的结果Flow private val searchResultCache = mutableMapOf<String, Flow<PagingData<Photo>>>() fun searchPhotoList(query: String): Flow<PagingData<Photo>> { return searchResultCache.getOrPut(query) { // 这里保留你原来的Paging请求逻辑 Pager( config = PagingConfig(pageSize = 20), pagingSourceFactory = { PhotoSearchPagingSource(query) } ).flow.cachedIn(viewModelScope) } } }
getOrPut会先检查缓存中是否已有该Query的结果Flow,有则直接返回,没有才发起新请求并存入缓存cachedIn(viewModelScope)确保Flow的生命周期和ViewModel绑定,避免内存泄漏
2. 优化LiveData观察逻辑,避免重复触发
在Fragment的onViewCreated中,对userSearchQuery的观察添加distinctUntilChanged(),确保只有Query真正变化时才触发请求:
searchViewModel.userSearchQuery.distinctUntilChanged().observe(viewLifecycleOwner) { query -> query?.let { lifecycleScope.launch { searchViewModel.searchPhotoList(query).collectLatest { photoList -> singlePhotoListAdapter.submitData(photoList) } } } }
distinctUntilChanged()会过滤掉和上一次相同的Query,避免Fragment回到前台时,因LiveData重发旧值而触发重复请求
3. 确认Navigation配置无异常
检查导航图(nav_graph.xml)中,从SearchPhotosFragment到WallpaperPreviewFragment的跳转配置,确保没有设置popUpTo或popUpToInclusive="true"导致SearchPhotosFragment被弹出栈。如果Fragment被弹出,返回时会重新创建,必然触发重新加载。
额外说明
retainInstance=true在AndroidX Fragment中已被废弃,使用ViewModel存储状态才是标准方案- 拦截返回键无法解决根本问题,问题本质是状态未被正确缓存,而非返回事件的处理
内容的提问来源于stack exchange,提问作者Pratik Fagadiya
相关产品推荐
相关产品推荐

