1

I need to upload file from device to my app. I use WorkManager to do it in background.

After updating library from android.arch.work:work-runtime:1.0.0-alpha04 to androidx.work:work-runtime:2.0.0 something goes wrong.

Method doWork() not calling in my UploadFileTask(workerParams: WorkerParameters) : Worker(Application.getContext(), workerParams)

Here is how I run my uploading:

fun upload(id: String, file: File, params: FileStorage.DocParams?, additionalTag: String): File {
    cancelUploadIfWas(file)
    fileStorage.save(file, params)
    val inputData = Data.Builder().putString(FileTask.PATH_KEY, file.path).build()
    val uploadWork = OneTimeWorkRequest.Builder(UploadFileTask::class.java)
        .addTag(ID_PREFIX + id)
        .addTag(PATH_PREFIX + file.path)
        .addTag(UPLOAD_TAG)
        .addTag(additionalTag)
        .keepResultsForAtLeast(0, TimeUnit.SECONDS)
        .setInputData(inputData)
        .build()

    workManager.enqueue(uploadWork)
    file.uploadStatus.onLoading()
    file.uploadWork=uploadWork
    uploadingFiles.put(ID_PREFIX + id, file)
    workManager.getWorkInfoByIdLiveData(uploadWork.id).observe(this, uploadObserver)
    return file
}

But my uploadObserver receives State.FAILED exactly after State.ENQUEUED

What I'm doing wrong?

Anton Prokopov
  • 639
  • 6
  • 27

2 Answers2

3

Solved

The trick was in that we have to create out task by this way:

UploadFileTask(context: Context, workerParams: WorkerParameters) : Worker(context, workerParams)

The constructor of our task have to receive exactly two parameters: context: Context and workerParams: WorkerParameters

Explanation:

val downloadWork = OneTimeWorkRequest.Builder(downloadingTask)
            .addTag(ID_TAG)
            .keepResultsForAtLeast(0, TimeUnit.SECONDS)
            .build()

workManager.enqueue(downloadWork)

WorkManager expects to receive downloadWork which was biult with downloadingTask, that has exactly two params in its constructor

Anton Prokopov
  • 639
  • 6
  • 27
  • Could you be specific? What exactly was the change u did? I also have this two param constructor, but neither the constructor is called nor dowork() !!! could you tell me pls!! – adi Mar 11 '20 at 15:11
  • 1
    @adi First I did like this: ```UploadFileTask(workerParams: WorkerParameters): Worker(Application.getContext(), workerParams)``` There was not context parameter in my ```UploadFileTask``` constructor. But in fact system needs both two parameters in task constructor: ```UploadFileTask(context: Context, workerParams: WorkerParameters) : Worker(context, workerParams)``` – Anton Prokopov Mar 12 '20 at 11:24
  • @adi I added an explanation to my answer – Anton Prokopov Mar 12 '20 at 11:38
  • Thanks for the inputs.I have posted a question regarding this.If possible kindly have a look at it: https://stackoverflow.com/questions/60644939/android-workmanager-not-starting-the-worker – adi Mar 12 '20 at 12:36
0

Have you tried to check the size of your payload/data that you're sending to your worker?
Sometimes when your data object is too large for the worker limits, the doWork() may not be called.

Or, it could be some exception thrown in your doWork() method without you noticing it, so it's failing to proceed with further code executions.

You can try to:

  • Remove setInputData() from your upload method
  • Remove getInputData() from your WorkManager class
  • Now a Log to your doWork() method to check if it's being called
  • 1
    Hi! Thank you for your answer. The issue was caused with that I used only one param in my Task constructor: ```UploadFileTask(context: Context, workerParams: WorkerParameters) : Worker(context, workerParams)```. There is some reflection under the hood in WorkManager, so the number of params in constructor matters. – Anton Prokopov Jan 17 '22 at 07:02
  • Yes, this must affect the Worker too.. – Hussein Nasereddine Jan 17 '22 at 08:44