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

Android中如何让OkHttpClient请求完成后再返回主Activity?

解决方案

核心思路是让次级Activity在网络请求完成(成功/失败)后,再通过setResult返回数据并关闭自身,而不是提前调用finish()。具体实现步骤如下:

1. 改造次级Activity的网络请求逻辑

发起请求后不要立刻关闭Activity,而是在OkHttp的回调方法中处理完数据后,再返回结果并结束Activity:

// 次级Activity内的代码
OkHttpClient client = new OkHttpClient();
RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), someRequest.toString());
Request request = new Request.Builder().url(myURL).post(body).build();

// 可选:显示加载提示,避免用户误以为界面无响应
ProgressDialog loadingDialog = ProgressDialog.show(this, "加载中", "正在获取数据...", true, false);

client.newCall(request).enqueue(new Callback() {
    @Override
    public void onFailure(@NonNull Call call, @NonNull IOException e) {
        e.printStackTrace();
        // 请求失败,返回错误信息
        runOnUiThread(() -> {
            loadingDialog.dismiss();
            Intent resultIntent = new Intent();
            resultIntent.putExtra("error", e.getMessage());
            setResult(RESULT_CANCELED, resultIntent);
            finish();
        });
    }

    @Override
    public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
        if (response.isSuccessful()) {
            String responseStr = response.body().string();
            // 将返回的JSON解析为自定义数据对象
            YourDataModel dataModel = parseJsonToModel(responseStr);

            runOnUiThread(() -> {
                loadingDialog.dismiss();
                Intent resultIntent = new Intent();
                // 注意:自定义对象需实现Parcelable/Serializable接口才能通过Intent传递
                resultIntent.putExtra("result_data", dataModel);
                setResult(RESULT_OK, resultIntent);
                finish();
            });
        } else {
            // 响应成功但状态码异常
            runOnUiThread(() -> {
                loadingDialog.dismiss();
                Intent resultIntent = new Intent();
                resultIntent.putExtra("error", "请求失败,响应码:" + response.code());
                setResult(RESULT_CANCELED, resultIntent);
                finish();
            });
        }
    }
});

2. 主Activity处理返回结果

在ActivityResultLauncher中接收次级Activity返回的数据:

// 主Activity内的ActivityResultLauncher
ActivityResultLauncher<Intent> someActivityResultLauncher = registerForActivityResult(
    new ActivityResultContracts.StartActivityForResult(),
    result -> {
        if (result.getResultCode() == Activity.RESULT_OK) {
            Intent data = result.getData();
            if (data != null) {
                // 获取返回的自定义数据对象
                YourDataModel resultData = data.getParcelableExtra("result_data");
                // 在这里处理数据
            }
        } else {
            // 处理请求失败的情况
            String errorMsg = result.getData() != null ? result.getData().getStringExtra("error") : "未知错误";
            // 提示用户错误信息,比如Toast.makeText(this, errorMsg, Toast.LENGTH_SHORT).show();
        }
    }
);

关键注意事项

  • 必须在runOnUiThread中执行界面更新(关闭加载对话框)和finish():OkHttp的回调默认在子线程,Android不允许在子线程操作UI或调用Activity生命周期方法。
  • 自定义数据对象需实现Parcelable(推荐,效率更高)或Serializable接口,才能通过Intent传递。
  • 绝对不能用execute()同步执行网络请求:这会导致主线程阻塞,触发NetworkOnMainThreadException,甚至引发ANR(应用无响应)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 15:45:48