Android Navigation Component返回时Fragment重复触发API请求问题排查
问题根因
- 你在
onCreateView生命周期中每次都调用termsViewModel.init(getContext())触发接口请求,使用Navigation组件导航返回时,Fragment会走视图重建流程,onCreateView会重复执行,直接导致接口反复调用 - 当前
init方法没有请求状态判断,每次调用都会触发新的API请求,就算MutableLiveData已经有缓存值也会重复执行请求逻辑 - 当前
new ViewModelProvider(this).get(TermsViewModel.class)的写法作用域是当前Fragment实例,Navigation返回栈中的Fragment实例不会被销毁,所以terms的LiveData缓存实际是存在的,只是重复的请求逻辑覆盖了正常的缓存复用逻辑
修复方案
1. 给ViewModel增加请求状态判断,避免重复触发API
修改TermsViewModel代码,增加请求标记防止重复调用:
public class TermsViewModel extends ViewModel implements Onresponse { public MutableLiveData<String> terms; Context context=null; // 新增请求完成标记,防止重复请求 private boolean isDataFetched = false; public TermsViewModel() { terms = new MutableLiveData<>(); } public void init(Context context){ // 已经请求过数据直接返回,不重复调用接口 if (isDataFetched) { return; } this.context=context; Map<String,Object> body=new HashMap<>(); body.put("st", Api.app_data); body.put("id",1); body.put("lg",Constant.langstr); Constant.connect(context,Api.app_data,body,this::onResponse,false); isDataFetched = true; } @Override public void onResponse(String st, JSONObject object, int online) { if(object!=null) { try { terms.setValue(object.getString("data")); } catch (JSONException e) { e.printStackTrace(); } } } }
2. 可选优化
如果请求参数不需要依赖Fragment的运行时动态参数,可以直接把请求逻辑移到ViewModel构造方法中执行,完全避免View层触发请求的风险。
你当前使用getViewLifecycleOwner作为LiveData观察的生命周期所有者是正确的,和Fragment视图生命周期绑定不会出现内存泄露,视图重建后观察会自动接收LiveData已有的缓存值,不需要额外调整。如果后续需要手动刷新数据,可以单独新增refresh方法,重置isDataFetched为false后再执行请求逻辑即可。
内容的提问来源于stack exchange,提问作者M000
相关产品推荐
相关产品推荐

