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;
}
}
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;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With