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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 06:54:08