Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Work Manager One time Request returns blank result from worker

I am using Work Manger to make a network call and fetch some data, for that I've used OneTimeRequest. The call responses perfectly inside the worker class but it returns blank result in the Life cycle Owner that is watching the work.

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);

For observing the response from the worker class

 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("")){
            }
        }
    });

But the thing is, the response string is always blank!! Even if the work manager has completed the task and the network response is there in worker but when i use setOutputData it gives blank data.

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);

Worker Class

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;
}

}

like image 968
AndroMasPC Avatar asked Dec 05 '22 11:12

AndroMasPC


1 Answers

The problem is that you are returning Result.Success before onResponse is triggered as you are doing an async retrofit request, hence no data being set in worker status.

One of the many workaround is that you send an synchronous retrofit request within your worker, thus your doWork() method will be blocked until you get a network response. You have to change your async retrofit request to synchronous, something like the following code snippet:

    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;
       }
    }
like image 55
Qasim Avatar answered Dec 28 '22 08:12

Qasim