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

如何将Volley回调中的异常抛出到外部fetchAdmins方法?

问题解答

首先,直接在Volley的异步回调中抛出异常到外部的fetchAdmins方法是不可行的,核心原因有两点:

  1. Volley的onResponse和onErrorResponse是异步回调方法,它们运行在独立的工作线程,和调用fetchAdmins的线程不是同一个,异步操作的异常无法直接同步传递到调用线程。
  2. 这两个回调方法的接口签名并未声明抛出checked异常(比如JSONException),强行抛出会触发编译错误。

以下是三种可行的解决方案:

方案一:同步阻塞实现(CountDownLatch)

将异步请求转为同步调用,让fetchAdmins方法阻塞等待请求完成,再将异常抛出。注意:该方案会阻塞调用线程,绝对不能在UI线程使用,避免引发ANR(应用无响应)。

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicReference;
import com.android.volley.Request;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonArrayRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONArray;
import org.json.JSONException;

public void fetchAdmins() throws JSONException, VolleyError {
    final CountDownLatch latch = new CountDownLatch(1);
    final AtomicReference<JSONException> jsonExceptionRef = new AtomicReference<>();
    final AtomicReference<VolleyError> volleyErrorRef = new AtomicReference<>();

    JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(
            Request.Method.GET,
            "你的API接口地址",
            null,
            response -> {
                try {
                    // 这里写你的JSON解析逻辑
                    for (int i = 0; i < response.length(); i++) {
                        JSONObject admin = response.getJSONObject(i);
                        // 解析操作...
                    }
                } catch (JSONException error) {
                    jsonExceptionRef.set(error);
                } finally {
                    latch.countDown(); // 请求完成,释放阻塞
                }
            },
            error -> {
                volleyErrorRef.set(error);
                latch.countDown(); // 请求失败,释放阻塞
            }
    );

    // 将请求加入Volley队列
    Volley.newRequestQueue(this).add(jsonArrayRequest);

    try {
        latch.await(); // 阻塞等待请求结束
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        throw new RuntimeException("请求被中断", e);
    }

    // 检查异常并抛出到fetchAdmins方法外
    if (jsonExceptionRef.get() != null) {
        throw jsonExceptionRef.get();
    }
    if (volleyErrorRef.get() != null) {
        throw volleyErrorRef.get();
    }
}

方案二:自定义回调接口(推荐)

遵循Volley的异步设计初衷,通过自定义回调接口传递结果和异常,避免线程阻塞。

首先定义回调接口:

import org.json.JSONException;
import com.android.volley.VolleyError;
import java.util.List;

public interface AdminFetchCallback {
    void onSuccess(List<Admin> admins); // 假设你有Admin实体类
    void onJsonParseError(JSONException error);
    void onRequestFailed(VolleyError error);
}

修改fetchAdmins方法:

public void fetchAdmins(AdminFetchCallback callback) {
    JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(
            Request.Method.GET,
            "你的API接口地址",
            null,
            response -> {
                try {
                    List<Admin> admins = new ArrayList<>();
                    for (int i = 0; i < response.length(); i++) {
                        JSONObject adminObj = response.getJSONObject(i);
                        admins.add(new Admin(adminObj.getString("id"), adminObj.getString("name")));
                    }
                    callback.onSuccess(admins);
                } catch (JSONException error) {
                    callback.onJsonParseError(error);
                }
            },
            error -> callback.onRequestFailed(error)
    );

    Volley.newRequestQueue(this).add(jsonArrayRequest);
}

调用示例:

fetchAdmins(new AdminFetchCallback() {
    @Override
    public void onSuccess(List<Admin> admins) {
        // 处理成功获取到的管理员列表
    }

    @Override
    public void onJsonParseError(JSONException error) {
        // 处理JSON解析异常
    }

    @Override
    public void onRequestFailed(VolleyError error) {
        // 处理Volley请求异常
    }
});

方案三:使用CompletableFuture(Java 8+)

利用Java 8引入的CompletableFuture包装异步操作,更简洁地处理结果和异常:

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import com.android.volley.Request;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonArrayRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public CompletableFuture<List<Admin>> fetchAdmins() {
    CompletableFuture<List<Admin>> future = new CompletableFuture<>();

    JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(
            Request.Method.GET,
            "你的API接口地址",
            null,
            response -> {
                try {
                    List<Admin> admins = new ArrayList<>();
                    for (int i = 0; i < response.length(); i++) {
                        JSONObject adminObj = response.getJSONObject(i);
                        admins.add(new Admin(adminObj.getString("id"), adminObj.getString("name")));
                    }
                    future.complete(admins);
                } catch (JSONException error) {
                    future.completeExceptionally(error);
                }
            },
            error -> future.completeExceptionally(error)
    );

    Volley.newRequestQueue(this).add(jsonArrayRequest);

    return future;
}

调用示例:

fetchAdmins()
        .thenAccept(admins -> {
            // 处理成功结果
        })
        .exceptionally(throwable -> {
            if (throwable instanceof JSONException) {
                // 处理JSON解析异常
            } else if (throwable instanceof VolleyError) {
                // 处理Volley请求异常
            }
            return null;
        });

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 10:20:40