Why is Android Worker finishing successfully and calling onStopped()

后端 未结 3 919
情深已故
情深已故 2021-01-13 07:55

My current Android app employs androidx.work:work-runtime:2.2.0-rc01

My Worker code resembles this:-

class SyncWorker(context: Context,          


        
相关标签:
3条回答
  • 2021-01-13 08:14

    I've created a simple example: it just starts the SyncWorker you are provided when a button is clicked. No sequential workers are started, just one worker, I even simplified the worker creation:

    val refreshDatabaseWork: OneTimeWorkRequest = OneTimeWorkRequest.Builder(SyncWorker::class.java)
        .build()
    
    WorkManager
        .getInstance(application)
        .enqueue(refreshDatabaseWork)
    

    When I press the button, sometimes the onStopped() is called, sometimes isn't. It's called very rarely, about one time per 20 clicks. Such inconsistent behavior looks like a bug indeed. There is onExecuted() callback method in the Processor implementation that is called each time when the worker finishes:

    @Override
    public void onExecuted(
        @NonNull final String workSpecId,
        boolean needsReschedule
    ) {
        synchronized (mLock) {
            mEnqueuedWorkMap.remove(workSpecId);
            Logger.get().debug(TAG, String.format("%s %s executed; reschedule = %s",
                    getClass().getSimpleName(), workSpecId, needsReschedule));
    
            for (ExecutionListener executionListener : mOuterListeners) {
                executionListener.onExecuted(workSpecId, needsReschedule);
            }
        }
    }
    

    This method removes the worker wrapper from mEnqueuedWorkMap, but sometimes stopWork() method gets the wrapper before it's removed, and as a result the worker is stopped and onStopped() callback is called.

    Also I've noticed that wrapper.interrupt(false) call receives cancelled boolean flag which is false in our case, but the flag is never used by the method, it also looks strange.

    I've also tried androidx.work:work-runtime:2.2.0, which is now available, but the result is the same. I think it's better to create a google issue to get an answer from the library developers. The behavior looks very strange, but I can only guess what it's intended to be.

    0 讨论(0)
  • 2021-01-13 08:21

    Its working as expected as per the documentation which for "Worker" class says:

    Once you return from this * method, the Worker is considered to have finished what its doing and will be destroyed. If * you need to do your work asynchronously on a thread of your own choice

    And also for onStopped() method of ListenableWorker class.

     /**
         * This method is invoked when this Worker has been told to stop.  This could happen due
         * to an explicit cancellation signal by the user, or because the system has decided to preempt
         * the task.  In these cases, the results of the work will be ignored by WorkManager.  All
         * processing in this method should be lightweight - there are no contractual guarantees about
         * which thread will invoke this call, so this should not be a long-running or blocking
         * operation.
         */
    
    0 讨论(0)
  • 2021-01-13 08:31

    The bug is already fixed in version 2.3.0-alpha02 and higher. So I changed my dependencies and I couldn't reproduce it anymore:

    implementation "androidx.work:work-runtime:2.3.0-alpha03"
    
    0 讨论(0)
提交回复
热议问题