Android Work Manager一次性请求返回工作者的空白结果

And*_*sPC 2 android android-workmanager

我正在使用工作管理器进行网络调用并获取一些数据,因为我已经使用了OneTimeRequest。该调用在worker类中响应完美,但在正在监视工作的“生命周期所有者”中返回空白结果。

workManager= WorkManager.getInstance();
    OneTimeWorkRequest.Builder encryptionWork =new OneTimeWorkRequest.Builder(NetworkWorker.class);

    getUsersWorkReq=encryptionWork.setInputData(getWorkerInput(EXPERT_LIST_REQUEST))
            .addTag(Constant.WORK_GETUSER)
            .build();

    workManager.enqueue(getUsersWorkReq);
Run Code Online (Sandbox Code Playgroud)

为了观察工人阶级的回应

 workManager.getStatusById(getUsersWorkReq.getId()).observe(this, workStatus -> {
        if (workStatus != null && workStatus.getState().isFinished()) {
            String status=workStatus.getOutputData().getString(Constant.WORK_RESULT);
            String response=workStatus.getOutputData().getString(Constant.WORK_RESPONSE);
            if(status!=null && !status.equalsIgnoreCase("")){
            }
        }
    });
Run Code Online (Sandbox Code Playgroud)

但问题是,响应字符串始终为空!即使工作经理已经完成任务并且工作人员中存在网络响应,但是当我使用setOutputData时,它也会提供空白数据。

outPut = new Data.Builder()
                        .putString(Constant.WORK_RESULT,Constant.WORK_SUCCESS)
                        .putString(Constant.WORK_RESPONSE, String.valueOf(response.body()))
                        .build();
                Log.e("WORKER", "onResponse: "+ response.body().getMsg() );
                setOutputData(outPut);
Run Code Online (Sandbox Code Playgroud)

工人阶级

public class NetworkWorker extends Worker {
Data outPut;
@NonNull
@Override
public Result doWork() {

        ApiService service = RetrofitInstance.getRetrofitInstance().create(ApiService.class);

        Call<ExpertListResponse> call = service.get_recommended_users();

        Log.wtf("URL Called", call.request().url() + "");

        call.enqueue(new Callback<ExpertListResponse>() {
            @Override
            public void onResponse(Call<ExpertListResponse> call, Response<ExpertListResponse> response) {
                //onFinishedListener.onFinished(requestTag, response.body() != null ? response.body().getExpertInfo() : null);
                Data outPut = new Data.Builder()
                        .putString(Constant.WORK_RESULT,Constant.WORK_SUCCESS)
                        .putString(Constant.WORK_RESPONSE, String.valueOf(response.code()))
                        .build();
                Log.e("WORKER", "onResponse: "+ response.body().getMsg() );
                setOutputData(outPut);
            }

            @Override
            public void onFailure(Call<ExpertListResponse> call, Throwable t) {
                //onFinishedListener.onFailure(requestTag,t);
                Data outPut = new Data.Builder()
                        .putString(Constant.WORK_RESULT,Constant.WORK_FAILURE)
                        .putString(Constant.WORK_RESPONSE, String.valueOf(t))
                        .build();
                setOutputData(outPut);
            }
        });

    return Result.SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)

}

Qas*_*sim 7

问题是您在执行异步改造请求时将返回Result.Success之前onResponse触发的消息,因此未在工作程序状态下设置任何数据。

许多解决方法之一是您在工作进程中发送同步改造请求,因此您的doWork()方法将被阻塞,直到获得网络响应为止。您必须将异步改造请求更改为同步请求,例如以下代码片段:

    public Result doWork() {
       try {
          ApiService service = RetrofitInstance.getRetrofitInstance()
                                   .create(ApiService.class);
          Call<ExpertListResponse> call = service.get_recommended_users();
          ExpertListResponse response = call.execute().body();
          Data outPut = new Data.Builder()
                    .putString(Constant.WORK_RESULT,Constant.WORK_SUCCESS)
                    .putString(Constant.WORK_RESPONSE, String.valueOf(response.code()))
                    .build();

          setOutputData(outPut);
          return Result.SUCCESS;
       } catch(Exception ex){
            Data outPut = new Data.Builder()
                    .putString(Constant.WORK_RESULT,Constant.WORK_FAILURE)
                    .putString(Constant.WORK_RESPONSE, String.valueOf(t))
                    .build();
            setOutputData(outPut);
            return Result.Failure;
       }
    }
Run Code Online (Sandbox Code Playgroud)


Rah*_*hul 5

你也可以使用这样的东西:

public class NetworkWorker extends Worker {

private static final long MAX_WAIT_TIME_SECONDS = 10L;

Data outPut;
CountDownLatch latch;

@NonNull
@Override
public Result doWork() {
    // Need to wait for the onResponse() call.
    latch = new CountDownLatch(1);

    ApiService service = RetrofitInstance.getRetrofitInstance().create(ApiService.class);
    Call<ExpertListResponse> call = service.get_recommended_users();
    call.enqueue(new Callback<ExpertListResponse>() {
        @Override
        public void onResponse(Call<ExpertListResponse> call, Response<ExpertListResponse> response) {
            Data outPut = new Data.Builder()
                    .putString(Constant.WORK_RESULT,Constant.WORK_SUCCESS)
                    .putString(Constant.WORK_RESPONSE, String.valueOf(response.code()))
                    .build();
            Log.e("WORKER", "onResponse: "+ response.body().getMsg() );
            latch.countdown();
            setOutputData(outPut);
        }

        @Override
        public void onFailure(Call<ExpertListResponse> call, Throwable t) {
            Data outPut = new Data.Builder()
                    .putString(Constant.WORK_RESULT,Constant.WORK_FAILURE)
                    .putString(Constant.WORK_RESPONSE, String.valueOf(t))
                    .build();
            latch.countdown();
            setOutputData(outPut);
        }
    });

latch.await(MAX_WAIT_TIME_SECONDS, TimeUnit.SECONDS);
return Result.SUCCESS;
Run Code Online (Sandbox Code Playgroud)

}

这个想法是通过 Retrofit 本身公开一个同步 API,或者使用CountDownLatch. 请记住,当您执行此类操作时,您可能会在线程池中使用额外的线程(因为 Retrofit 可能会使用不同的线程池)。