When using WorkManager to perform the only task, after an error occurs in doWork() and the handling exception is Result.failure(), doWork() will be called again.
I tried to troubleshoot the error through the log file, and I found that the setComponentEnabled(context, SystemJobService.class, true);
of androidx.work.impl.Schedulers#createBestAvailableBackgroundScheduler
was called twice. WorkManagerImpl
is a singleton object and will not be called twice. So I am very confused.
01-15 15:25:01.198 7797 7797 D WM-PackageManagerHelper: androidx.work.impl.background.systemjob.SystemJobService enabled
01-15 15:25:01.198 7797 7797 D WM-Schedulers: Created SystemJobScheduler and enabled SystemJobService
01-15 15:25:01.208 7797 7847 D WM-ForceStopRunnable: Performing cleanup operations.
01-15 15:25:01.303 7797 7851 D WM-PackageManagerHelper: androidx.work.impl.background.systemalarm.RescheduleReceiver enabled
01-15 15:25:01.319 7797 7851 D WM-SystemJobScheduler: Scheduling work ID b278a34c-aeeb-4c88-8f29-71b9c23e0954 Job ID 68
01-15 15:25:01.327 7797 7851 D WM-GreedyScheduler: Starting work for b278a34c-aeeb-4c88-8f29-71b9c23e0954
01-15 15:25:01.334 7797 7858 D WM-Processor: Processor: processing b278a34c-aeeb-4c88-8f29-71b9c23e0954
01-15 15:25:02.742 7797 7797 D WM-WorkerWrapper: Starting work for my_package.service.StatisticsService
01-15 15:25:02.822 7797 7847 D WM-WorkerWrapper: my_package.service.StatisticsService returned a Failure {mOutputData=Data {}} result.
01-15 15:25:02.829 7797 7847 I WM-WorkerWrapper: Worker result FAILURE for Work [ id=b278a34c-aeeb-4c88-8f29-71b9c23e0954, tags={ my_package.service.StatisticsService } ]
01-15 15:25:02.842 7797 7847 D WM-PackageManagerHelper: androidx.work.impl.background.systemalarm.RescheduleReceiver disabled
01-15 15:25:02.847 7797 7797 D WM-SystemJobService: onStartJob for b278a34c-aeeb-4c88-8f29-71b9c23e0954
01-15 15:25:02.847 7797 7847 D WM-GreedyScheduler: Cancelling work ID b278a34c-aeeb-4c88-8f29-71b9c23e0954
01-15 15:25:02.862 7797 7851 D WM-Processor: Work b278a34c-aeeb-4c88-8f29-71b9c23e0954 is already enqueued for processing
01-15 15:25:02.868 7797 7851 D WM-Processor: Processor stopping background work b278a34c-aeeb-4c88-8f29-71b9c23e0954
01-15 15:25:02.869 7797 7851 D WM-WorkerWrapper: Work interrupted for Work [ id=b278a34c-aeeb-4c88-8f29-71b9c23e0954, tags={ my_package.service.StatisticsService } ]
01-15 15:25:02.883 7797 7851 D WM-PackageManagerHelper: androidx.work.impl.background.systemalarm.RescheduleReceiver disabled
01-15 15:25:02.884 7797 7851 D WM-WorkerWrapper: WorkSpec {WorkSpec: b278a34c-aeeb-4c88-8f29-71b9c23e0954} is already done. Not interrupting.
01-15 15:25:02.884 7797 7851 D WM-Processor: WorkerWrapper interrupted for b278a34c-aeeb-4c88-8f29-71b9c23e0954
01-15 15:25:02.884 7797 7851 D WM-StopWorkRunnable: StopWorkRunnable for b278a34c-aeeb-4c88-8f29-71b9c23e0954; Processor.stopWork = true
01-15 15:25:02.899 7797 7797 D WM-Processor: Processor b278a34c-aeeb-4c88-8f29-71b9c23e0954 executed; reschedule = false
01-15 15:25:02.900 7797 7797 D WM-SystemJobService: b278a34c-aeeb-4c88-8f29-71b9c23e0954 executed on JobScheduler
01-15 15:25:02.900 7797 7797 D WM-SystemJobService: onStopJob for b278a34c-aeeb-4c88-8f29-71b9c23e0954
01-15 15:25:02.903 7797 7847 D WM-Processor: Processor stopping background work b278a34c-aeeb-4c88-8f29-71b9c23e0954
01-15 15:25:02.903 7797 7847 D WM-Processor: WorkerWrapper could not be found for b278a34c-aeeb-4c88-8f29-71b9c23e0954
01-15 15:25:02.904 7797 7847 D WM-StopWorkRunnable: StopWorkRunnable for b278a34c-aeeb-4c88-8f29-71b9c23e0954; Processor.stopWork = false
// Here doWork() is repeated once.
01-15 15:25:04.511 7923 7923 D WM-PackageManagerHelper: androidx.work.impl.background.systemjob.SystemJobService enabled
01-15 15:25:04.511 7923 7923 D WM-Schedulers: Created SystemJobScheduler and enabled SystemJobService
01-15 15:25:04.519 7923 7985 D WM-ForceStopRunnable: Performing cleanup operations.
01-15 15:25:04.600 7923 7989 D WM-PackageManagerHelper: androidx.work.impl.background.systemalarm.RescheduleReceiver enabled
01-15 15:25:04.616 7923 7989 D WM-SystemJobScheduler: Scheduling work ID 07bddcf0-33c3-43c5-ad2b-0dcb1f200e18 Job ID 69
01-15 15:25:04.624 7923 7989 I WM-GreedyScheduler: Ignoring schedule request in non-main process
01-15 15:25:04.633 7797 7797 D WM-SystemJobService: onStartJob for 07bddcf0-33c3-43c5-ad2b-0dcb1f200e18
01-15 15:25:04.634 7797 7851 D WM-Processor: Processor: processing 07bddcf0-33c3-43c5-ad2b-0dcb1f200e18
01-15 15:25:04.650 7797 7797 D WM-WorkerWrapper: Starting work for my_package.service.StatisticsService
01-15 15:25:04.697 7797 7847 D WM-WorkerWrapper: my_package.service.StatisticsService returned a Failure {mOutputData=Data {}} result.
01-15 15:25:04.700 7797 7847 I WM-WorkerWrapper: Worker result FAILURE for Work [ id=07bddcf0-33c3-43c5-ad2b-0dcb1f200e18, tags={ my_package.service.StatisticsService } ]
01-15 15:25:04.704 7797 7847 D WM-PackageManagerHelper: androidx.work.impl.background.systemalarm.RescheduleReceiver disabled
01-15 15:25:04.704 7797 7797 D WM-Processor: Processor 07bddcf0-33c3-43c5-ad2b-0dcb1f200e18 executed; reschedule = false
01-15 15:25:04.705 7797 7797 D WM-SystemJobService: 07bddcf0-33c3-43c5-ad2b-0dcb1f200e18 executed on JobScheduler
01-15 15:25:04.713 7797 7847 D WM-GreedyScheduler: Cancelling work ID 07bddcf0-33c3-43c5-ad2b-0dcb1f200e18
01-15 15:25:04.718 7797 7847 D WM-Processor: Processor stopping background work 07bddcf0-33c3-43c5-ad2b-0dcb1f200e18
01-15 15:25:04.719 7797 7847 D WM-Processor: WorkerWrapper could not be found for 07bddcf0-33c3-43c5-ad2b-0dcb1f200e18
01-15 15:25:04.719 7797 7847 D WM-StopWorkRunnable: StopWorkRunnable for 07bddcf0-33c3-43c5-ad2b-0dcb1f200e18; Processor.stopWork = false
I need to perform a task that is only executed once every time I open the app to upload my statistics, and if there is no network, cache it.
jetpack workmanager 2.4.0
Application.java
// Start a background only task.
StatisticsService.startService(getApplicationContext());
StatisticsService.java
public static void startService(Context context) {
OneTimeWorkRequest.Builder builder = new OneTimeWorkRequest.Builder(StatisticsService.class);
...
Data.Builder data = new Data.Builder();
data.putBoolean(EXTRA_IS_FIRST, isFirstOpenApp);
builder.setInputData(data.build());
WorkManager.getInstance(context).enqueueUniqueWork("StatisticsService", ExistingWorkPolicy.APPEND_OR_REPLACE, builder.build());
}
@NonNull
@Override
public Result doWork() {
log.info("doWork:" + hashCode());
boolean isSuccessful = false;
try {
Data inputData = getInputData();
boolean isFirstOpenApp = inputData.getBoolean(EXTRA_IS_FIRST, true);
isSuccessful = uploadStatisticsInfo(isFirstOpenApp);
if (isSuccessful) {
return Result.success();
} else {
return Result.failure();
}
} catch (Exception e) {
log.severe(ThrowableUtils.getFullStackTrace(e));
return Result.failure();
}
}
private boolean uploadStatisticsInfo(boolean isFirstOpenApp) {
// Synchronously determine whether the network is available.
// If the network is unavailable, an exception will be thrown.
boolean available = NetworkUtils.isAvailable();
if (!available) {
AppStatisticsBean.cacheOneMap(isFirstOpenApp);
return false;
}
// Upload statistics
...
if (success){
return true;
} else {
return false;
}
}
You are enqueuing your WorkRequest as a unique work with a ExistingWorkPolicy.APPEND_OR_REPLACE
policy. This means that if there is already another request pending, the new one is appended to the existing one creating a chain of work.
The replace part is only used if the previous work has failed.
Creating a chain of work, once a worker is executed correctly, the next one in the chain is going to be executed. This is explained in WorkManager's documentation .
An alternative is to use the ExistingWorkPolicy.KEEP
policy so that only one WorkRequest is going to be enqueued.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.