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

Android LiveData实现顺序网络请求(无RxJava)方案咨询

如何用Retrofit+LiveData实现顺序网络请求(无需RxJava)

我完全懂你现在的痛点——用多个LiveData观察者嵌套处理顺序请求,不仅代码看起来乱糟糟,还容易出现状态管理的漏洞。其实咱们可以把整个顺序请求的逻辑封装在ViewModel层,让视图层只需要观察一个统一的结果LiveData,这样代码会清晰很多,维护起来也更省心。

核心思路

  • 在ViewModel中创建一个专门的LiveData,用来暴露整个流程的状态(加载中/成功/失败)
  • 内部监听仓库层返回的请求结果:等createItems成功后再触发deleteItem,任一环节失败就立刻终止流程并返回错误
  • 借助observeForever+手动移除观察者的方式,避免在视图层做嵌套观测,同时防止内存泄漏

具体代码改造

1. ViewModel层:封装顺序请求逻辑

我们新增一个处理顺序请求的方法,以及对应的结果LiveData,把所有链式请求的逻辑都放在这里:

private final MutableLiveData<Resource<Void>> sequentialRequestResult = new MutableLiveData<>();
public LiveData<Resource<Void>> getSequentialRequestResult() {
    return sequentialRequestResult;
}

// 执行「创建+删除」的顺序请求
public void executeCreateThenDelete(String id) {
    sequentialRequestResult.setValue(Resource.loading(null));
    
    // 第一步:执行创建请求
    LiveData<Resource<List<Items>>> createLiveData = eventItemRepository.createItems();
    createLiveData.observeForever(new Observer<Resource<List<Items>>>() {
        @Override
        public void onChanged(Resource<List<Items>> createResult) {
            createLiveData.removeObserver(this); // 用完立刻移除,避免内存泄漏
            if (createResult.status == Status.SUCCESS) {
                // 创建成功,执行第二步:删除请求
                LiveData<Resource<EmptyResponse>> deleteLiveData = eventItemRepository.deleteItem(id);
                deleteLiveData.observeForever(new Observer<Resource<EmptyResponse>>() {
                    @Override
                    public void onChanged(Resource<EmptyResponse> deleteResult) {
                        deleteLiveData.removeObserver(this);
                        if (deleteResult.status == Status.SUCCESS) {
                            sequentialRequestResult.postValue(Resource.success(null));
                        } else {
                            sequentialRequestResult.postValue(Resource.error(deleteResult.message, null));
                        }
                    }
                });
            } else {
                // 创建失败,直接返回错误
                sequentialRequestResult.postValue(Resource.error(createResult.message, null));
            }
        }
    });
}

// 单独执行删除请求的方法(对应原逻辑中的isCustomizedItem分支)
public void executeDeleteOnly(String id) {
    sequentialRequestResult.setValue(Resource.loading(null));
    LiveData<Resource<EmptyResponse>> deleteLiveData = eventItemRepository.deleteItem(id);
    deleteLiveData.observeForever(new Observer<Resource<EmptyResponse>>() {
        @Override
        public void onChanged(Resource<EmptyResponse> deleteResult) {
            deleteLiveData.removeObserver(this);
            if (deleteResult.status == Status.SUCCESS) {
                sequentialRequestResult.postValue(Resource.success(null));
            } else {
                sequentialRequestResult.postValue(Resource.error(deleteResult.message, null));
            }
        }
    });
}

2. 视图层:简化为单一观察者

现在视图层只需要调用对应的方法,然后观察一个LiveData就能处理所有状态:

String id = "items/1233";
if (isCustomizedItem) {
    viewModel.executeDeleteOnly(id);
} else {
    viewModel.executeCreateThenDelete(id);
}

// 只需要监听这一个LiveData就够了
viewModel.getSequentialRequestResult().observe(this, result -> {
    if (result.status == Status.SUCCESS) {
        Timber.i("操作成功完成");
    } else if (result.status == Status.ERROR) {
        Timber.e("操作失败:%s", result.message);
        // 这里可以统一处理错误提示,比如Toast或弹窗
    } else if (result.status == Status.LOADING) {
        // 显示加载中UI,比如ProgressBar
    }
});

3. 优化:抽取通用工具方法

为了避免重复写observeForever和removeObserver的代码,咱们可以抽一个工具类:

public class LiveDataUtils {
    public static <T> void observeOnce(LiveData<T> liveData, Observer<T> observer) {
        liveData.observeForever(new Observer<T>() {
            @Override
            public void onChanged(T t) {
                liveData.removeObserver(this);
                observer.onChanged(t);
            }
        });
    }
}

之后ViewModel里的代码可以简化成这样:

// 执行创建请求的部分
LiveDataUtils.observeOnce(createLiveData, createResult -> {
    if (createResult.status == Status.SUCCESS) {
        LiveDataUtils.observeOnce(eventItemRepository.deleteItem(id), deleteResult -> {
            // 处理删除结果
        });
    } else {
        // 处理创建失败
    }
});

方案优势

  • 视图层代码极简:不用再处理多个观察者的嵌套,只关注最终的流程状态
  • 逻辑内聚:所有顺序请求、错误处理的逻辑都在ViewModel里,符合MVVM的架构原则
  • 状态统一:加载中、成功、失败的状态都通过同一个LiveData传递,避免状态不一致的问题

内容的提问来源于stack exchange,提问作者Saurabh Khare

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:44:20