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
相关产品推荐
相关产品推荐

