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

Work Manager问题:如何仅在网络请求完成后返回doWork()结果

问题分析

你的代码核心问题是Volley网络请求是异步执行的——调用addToRequestQueue后,请求会在后台线程悄悄跑,但putData方法会立刻返回还未被赋值的result[0],导致doWork提前结束,完全没等到PUT请求完成就返回了结果,自然达不到预期效果。

解决方案:用同步请求阻塞Worker线程

因为Worker本身就是在后台线程运行的,我们可以把异步请求改成同步模式,让线程等待网络请求完成后再返回结果。Volley提供了RequestFuture来实现同步请求,这是最直接的方案。

修改后的代码如下:

public class MyWorker extends Worker {
    private Context context;

    public MyWorker(@NonNull Context context, @NonNull WorkerParameters params) {
        super(context, params);
        this.context = context;
    }

    @NonNull
    @Override
    public Result doWork() {
        return putData();
    }

    private Result putData() {
        String url = "https://www.myurl.com";
        // 创建RequestFuture对象,用于同步等待请求结果
        RequestFuture<JSONObject> future = RequestFuture.newFuture();
        
        JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.PUT, url, null, future, future);
        VolleyHelper.getInstance(context).addToRequestQueue(jsonObjectRequest);

        try {
            // 阻塞当前线程,直到请求完成或超时
            JSONObject response = future.get();
            return response == null ? Result.retry() : Result.success();
        } catch (InterruptedException e) {
            // 线程被中断,返回重试
            return Result.retry();
        } catch (ExecutionException e) {
            // 处理请求过程中的异常
            Throwable cause = e.getCause();
            if (cause instanceof TimeoutError || cause instanceof NoConnectionError || cause instanceof ServerError || cause instanceof NetworkError) {
                return Result.retry();
            } else if (cause instanceof AuthFailureError) {
                // 授权失败,直接返回失败
                return Result.failure();
            } else if (cause instanceof ParseError) {
                // 解析错误,返回失败
                return Result.failure();
            }
            return Result.failure();
        }
    }
}
关键修改说明
  • RequestFuture替代异步回调:RequestFuture同时实现了Response.Listener和Response.ErrorListener,把它传给请求后,调用future.get()会阻塞当前线程,直到请求成功拿到结果,或者抛出异常。
  • 移除冗余的result数组:不再需要用数组在异步回调里赋值,同步请求直接拿到结果,逻辑更清晰。
  • 异常统一处理:捕获future.get()抛出的中断异常和执行异常,根据错误类型返回对应的Result(重试或失败)。
额外提醒
  • 确保应用已经申请了INTERNET权限,VolleyHelper的单例配置正确。
  • 不要在Worker里用Toast,后台线程没有UI上下文,Toast不会显示,建议用Log.e()记录错误信息。
  • 可以通过WorkManager的RetryPolicy配置重试的间隔和次数,让任务重试更合理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:16:25