工作管理器:如何仅在网络请求完成时返回结果

Posted

技术标签:

【中文标题】工作管理器:如何仅在网络请求完成时返回结果【英文标题】:Work Manager: How to return result only when network request is done 【发布时间】:2020-04-12 00:06:01 【问题描述】:

这是我的工人阶级,我已经尝试过了,但似乎没有按照我想要的方式工作。我只想在 PUT 请求完成后返回 doWork() 的结果。任何帮助将不胜感激,谢谢。

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() 
    final Result[] result = new Result[1];
    String url = "https://www.myurl.com";
    JsonObjectRequest jsonObjectRequest = new JsonObjectRequest
            (Request.Method.PUT, url, null, new Response.Listener<JSONObject>() 

                @Override
                public void onResponse(JSONObject response) 
                    if(response == null)
                        result[0] = Result.retry();
                    else
                        result[0] = Result.success();
                
            , new Response.ErrorListener() 

                @Override
                public void onErrorResponse(VolleyError error) 
                    // TODO: Handle error
                    if (error instanceof TimeoutError || error instanceof NoConnectionError) 
                        result[0] = Result.retry();
                     else if (error instanceof AuthFailureError) 
                        //TODO
                     else if (error instanceof ServerError) 
                        //TODO
                        result[0] = Result.retry();
                     else if (error instanceof NetworkError) 
                        //TODO
                        result[0] = Result.retry();
                     else if (error instanceof ParseError) 
                        //TODO
                    
                    Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_LONG).show();
                
            ) 
        @Override
        public Map<String, String> getHeaders() throws AuthFailureError 
            return params;
        

        @Override
        protected Map<String, String> getParams() throws AuthFailureError 
            return super.getParams();
        
    ;

    VolleyHelper.getInstance(context).addToRequestQueue(jsonObjectRequest);
    return result[0];

【问题讨论】:

您必须等待响应,这可以通过 kotlin 和协程轻松完成。 您可以使用回调接口,在启动前向worker注册您的监听器,在putData()的完成时您可以通知您的监听器结果对象。 一个Worker 类只能执行同步代码。如果要执行异步操作,需要使用CoroutineWorkerListenableWorker 【参考方案1】:

感谢@pfmaggi,我能够做到这一点

interface MyCallback
    void onSuccess();
    void onError();


public class MyWorker extends ListenableWorker 
    private Context context;

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

     @NonNull
@Override
public ListenableFuture<Result> startWork() 
    return CallbackToFutureAdapter.getFuture(completer -> 
        MyCallback callback = new MyCallback() 
            @Override
            public void onSuccess() 
                completer.set(Result.success());
            

            @Override
            public void onError() 
                completer.set(Result.retry());
            
        ;
        putData(callback);
        return callback;
    );



    private void putData(MyCallback callback) 
        String url = "https://www.myurl.com";
        JsonObjectRequest jsonObjectRequest = new JsonObjectRequest
                (Request.Method.PUT, url, null, new Response.Listener<JSONObject>() 

                    @Override
                    public void onResponse(JSONObject response) 
                        if(response == null)
                            callback.onError();
                        else
                            callback.onSuccess();
                    
                , new Response.ErrorListener() 

                    @Override
                    public void onErrorResponse(VolleyError error) 
                        // TODO: Handle error
                        if (error instanceof TimeoutError || error instanceof NoConnectionError) 
                            callback.onError();
                         else if (error instanceof AuthFailureError) 
                            //TODO
                         else if (error instanceof ServerError) 
                            //TODO
                            callback.onError();
                         else if (error instanceof NetworkError) 
                            //TODO
                            callback.onError();
                         else if (error instanceof ParseError) 
                            //TODO
                        
                    
                ) 
            @Override
            public Map<String, String> getHeaders() throws AuthFailureError 
                return params;
            

            @Override
            protected Map<String, String> getParams() throws AuthFailureError 
                return super.getParams();
            
        ;

        VolleyHelper.getInstance(context).addToRequestQueue(jsonObjectRequest);
    

【讨论】:

官方文档:developer.android.com/topic/libraries/architecture/workmanager/…

以上是关于工作管理器:如何仅在网络请求完成时返回结果的主要内容,如果未能解决你的问题,请参考以下文章

如何在任务完成时更新运行结果?

Flutter 工作管理器返回“工作人员结果失败 [id=XXXXxXXXXXXXXXX 标签= be.tramckrijte.workmanager.BackgroundWorker ]”

Jmeter 实现上步请求返回结果 用于下步请求参数

查找谷歌地方自动完成时返回零结果

MYSQL 仅在询问第一个排名时不会在 PHP 中返回结果

如何从方法返回 alamofire Http 请求的结果?