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

如何等待Retrofit接口调用响应完成后再执行后续操作

问题核心原因

你当前使用enqueue方法发起异步Retrofit请求,该方法不会阻塞当前线程,会直接执行后续代码,所以不等接口返回结果就会执行return逻辑,自然无法保证接口调用成功后再执行后续Ticket插入逻辑。

可选实现方案

方案1:同步执行请求(适合简单场景,需注意线程调度)

直接使用execute方法同步执行请求,该方法会阻塞当前线程直到拿到接口响应,之后再返回结果。

注意

绝对不能在安卓主线程调用该方法,否则会触发NetworkOnMainThreadException异常,必须将整个saveListToDb逻辑放到子线程执行。

修改后的insertApi代码

public long insertApi(TicketListTable ticketListTable) throws IOException {
    Call<TicketListTable> ticketListTableCall = dataService.createTicketList(ticketListTable);
    // 同步执行网络请求,阻塞当前线程直到拿到响应
    Response<TicketListTable> response = ticketListTableCall.execute();
    if (response.isSuccessful()) {
        // 接口请求成功后再插入本地数据库,返回有效ID
        return repo.insert(ticketListTable);
    } else {
        // 接口请求失败返回无效ID,供上层判断
        return -1;
    }
}

方案2:异步回调链式调用(推荐,不会阻塞线程)

通过自定义回调接口,把后续插入Ticket的逻辑放到TicketList接口请求成功的回调中执行,避免线程阻塞问题。

第一步:定义回调接口

public interface InsertTicketListCallback {
    void onSuccess(long listId);
    void onFailure(Throwable error);
}

第二步:改造insertApi方法

public void insertApi(TicketListTable ticketListTable, InsertTicketListCallback callback) {
    Call<TicketListTable> ticketListTableCall = dataService.createTicketList(ticketListTable);
    ticketListTableCall.enqueue(new Callback<TicketListTable>() {
        @Override
        public void onResponse(Call<TicketListTable> call, Response<TicketListTable> response) {
            if (response.isSuccessful()) {
                long listId = repo.insert(ticketListTable);
                callback.onSuccess(listId);
            } else {
                callback.onFailure(new Exception("接口请求失败,错误码:" + response.code()));
            }
        }

        @Override
        public void onFailure(Call<TicketListTable> call, Throwable t) {
            callback.onFailure(t);
        }
    });
}

第三步:改造saveListToDb方法

public void saveListToDb(String[] split, String regexData){
    String newListName = listName.getText().toString();
    SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
    TicketListTable newTicketListTable = new TicketListTable();
    newTicketListTable.setTicketListName(newListName);
    newTicketListTable.setTicketListCreated(sd.format(Calendar.getInstance().getTime()));
    newTicketListTable.setTicketListUpdated(sd.format(Calendar.getInstance().getTime()));

    // 调用异步接口,在成功回调中执行后续Ticket插入逻辑
    ticketTableVm.insertApi(newTicketListTable, new InsertTicketListCallback() {
        @Override
        public void onSuccess(long ticketTableListId) {
            if(ticketTableListId <= 0){
                // 自定义处理本地插入失败逻辑
                return;
            }
            // 批量插入Ticket
            for (String s : split) {
                String[] values = s.split(regexData);
                String number = values[0].replace("\n", "").replace("\r", "");
                String info = values[1];
                String warningNote = values[2];
                String warning = values[3];
                String customer = values[4];
                int useable = Integer.parseInt(values[5].replaceAll("\\s+", "").replace("\n", "").replace("\r", ""));
                TicketTable ticketTable = new TicketTable(number, customer, info, warningNote, useable, ticketTableListId,warning);
                ticketTableVm.insert(ticketTable);
            }
            // 所有操作完成后自定义处理逻辑,如UI提示
        }

        @Override
        public void onFailure(Throwable t) {
            // 自定义处理请求失败逻辑,如日志打印、用户提示
            t.printStackTrace();
        }
    });
}
额外注意事项
  • 异步回调中如果需要更新UI,安卓平台下Retrofit默认回调运行在主线程,可直接操作UI;如果需要执行批量数据库插入等耗时操作,建议切到子线程执行避免卡顿。
  • 如果项目已接入Kotlin,可直接使用Retrofit的suspend挂起方法结合协程实现,代码更简洁,无需嵌套回调。

内容的提问来源于stack exchange,提问作者Vishav Lakhtia

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 13:39:03