Fixed
Status Update
Comments
ra...@google.com <ra...@google.com>
ra...@google.com <ra...@google.com>
at...@bloomberg.net <at...@bloomberg.net> #2
Which version is this fixed in? Using android.arch.work:work-runtime-ktx:1.0.0-alpha08, I am still seeing repeated work executed when the scheduler is initialised in application onCreate.
Managed to work around it by creating a OneTimeWorkRequestBuilder delegate that calls through to WorkManager.getInstance().enqueueUniquePeriodicWork(), but seems sub-optimal..
Managed to work around it by creating a OneTimeWorkRequestBuilder delegate that calls through to WorkManager.getInstance().enqueueUniquePeriodicWork(), but seems sub-optimal..
su...@google.com <su...@google.com> #3
Is your app being force-stopped prior to this? Can you please provide some sample code that reproduces the problem?
at...@bloomberg.net <at...@bloomberg.net> #4
Yes it would have been force-stopping on repeated Run 'app' triggers from Android Studio (v3.1.4).
Here is the sample code we tried:
package com.example.test.workmanagertest
import android.app.Application
import android.util.Log
import androidx.work.Constraints
import androidx.work.NetworkType
import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkManager
import androidx.work.Worker
import java.util.concurrent.TimeUnit
class App : Application() {
override fun onCreate() {
super.onCreate()
scheduleSomeWork()
}
fun scheduleSomeWork() {
Log.i("WorkManagerTest", "Scheduling some work")
val workRequestBuilder =
PeriodicWorkRequestBuilder<MyWorker>(10, TimeUnit.HOURS)
val constraints = Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build()
workRequestBuilder.setConstraints(constraints)
val work = workRequestBuilder.build()
WorkManager.getInstance().enqueue(work)
Log.i("WorkManagerTest", "Work scheduled")
}
}
class MyWorker : Worker() {
override fun doWork(): Result {
Log.i("WorkManagerTest.Worker", "I'm working")
return Result.SUCCESS
}
}
If I run it on an emulator (Android 8.0.0) N times, I can see "I'm working" in the log N times. What's interesting is that it doesn't happen every time (e.g. 2nd execution only logged once, 3rd execution logged 3 times, 4th and 5th executions only logged once, 6th execution logged 6 times, you get the idea..)
Running on a real Pixel XL device Android 9, behaviour was slightly different but equally broken. I could not replicate it by simply hitting the green play button in AS (ran it 8 times). Before the 9th re-execution, I turned on the device screen, tapped the device home key to background the app and then hit play again in AS:
09-11 05:44:50.350 8034-8060/? I/WorkManagerTest.Worker: I'm working
09-11 05:44:50.355 8034-8059/? I/WorkManagerTest.Worker: I'm working
09-11 05:44:50.358 8034-8061/? I/WorkManagerTest.Worker: I'm working
09-11 05:44:50.423 8034-8059/? I/WorkManagerTest.Worker: I'm working
09-11 05:44:50.424 8034-8060/? I/WorkManagerTest.Worker: I'm working
09-11 05:44:50.460 8034-8061/? I/WorkManagerTest.Worker: I'm working
09-11 05:44:50.463 8034-8060/? I/WorkManagerTest.Worker: I'm working
09-11 05:44:50.468 8034-8059/? I/WorkManagerTest.Worker: I'm working
09-11 05:44:50.517 8034-8060/? I/WorkManagerTest.Worker: I'm working
09-11 05:44:50.522 8034-8061/? I/WorkManagerTest.Worker: I'm working
This is a barebones sample with hello world MainActivity.kt and associated LinearLayout
App build.gradle for full reference:
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.example.test.workmanagertest"
minSdkVersion 23
targetSdkVersion 25
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'android.arch.work:work-runtime-ktx:1.0.0-alpha08'
}
(ext.kotlin_version = '1.2.60' FYI )
Here is the sample code we tried:
package com.example.test.workmanagertest
import android.app.Application
import android.util.Log
import androidx.work.Constraints
import androidx.work.NetworkType
import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkManager
import androidx.work.Worker
import java.util.concurrent.TimeUnit
class App : Application() {
override fun onCreate() {
super.onCreate()
scheduleSomeWork()
}
fun scheduleSomeWork() {
Log.i("WorkManagerTest", "Scheduling some work")
val workRequestBuilder =
PeriodicWorkRequestBuilder<MyWorker>(10, TimeUnit.HOURS)
val constraints = Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build()
workRequestBuilder.setConstraints(constraints)
val work = workRequestBuilder.build()
WorkManager.getInstance().enqueue(work)
Log.i("WorkManagerTest", "Work scheduled")
}
}
class MyWorker : Worker() {
override fun doWork(): Result {
Log.i("WorkManagerTest.Worker", "I'm working")
return Result.SUCCESS
}
}
If I run it on an emulator (Android 8.0.0) N times, I can see "I'm working" in the log N times. What's interesting is that it doesn't happen every time (e.g. 2nd execution only logged once, 3rd execution logged 3 times, 4th and 5th executions only logged once, 6th execution logged 6 times, you get the idea..)
Running on a real Pixel XL device Android 9, behaviour was slightly different but equally broken. I could not replicate it by simply hitting the green play button in AS (ran it 8 times). Before the 9th re-execution, I turned on the device screen, tapped the device home key to background the app and then hit play again in AS:
09-11 05:44:50.350 8034-8060/? I/WorkManagerTest.Worker: I'm working
09-11 05:44:50.355 8034-8059/? I/WorkManagerTest.Worker: I'm working
09-11 05:44:50.358 8034-8061/? I/WorkManagerTest.Worker: I'm working
09-11 05:44:50.423 8034-8059/? I/WorkManagerTest.Worker: I'm working
09-11 05:44:50.424 8034-8060/? I/WorkManagerTest.Worker: I'm working
09-11 05:44:50.460 8034-8061/? I/WorkManagerTest.Worker: I'm working
09-11 05:44:50.463 8034-8060/? I/WorkManagerTest.Worker: I'm working
09-11 05:44:50.468 8034-8059/? I/WorkManagerTest.Worker: I'm working
09-11 05:44:50.517 8034-8060/? I/WorkManagerTest.Worker: I'm working
09-11 05:44:50.522 8034-8061/? I/WorkManagerTest.Worker: I'm working
This is a barebones sample with hello world MainActivity.kt and associated LinearLayout
App build.gradle for full reference:
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.example.test.workmanagertest"
minSdkVersion 23
targetSdkVersion 25
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'android.arch.work:work-runtime-ktx:1.0.0-alpha08'
}
(ext.kotlin_version = '1.2.60' FYI )
su...@google.com <su...@google.com> #5
I believe what you're seeing is intended. You are enqueuing N periodic jobs. There is nothing unique about them (did you mean to use enqueueUniqueWork?). So there are N periodic jobs running in parallel.
The reason they run when the app is launched is that you are effectively force-stopping your app by using Android Studio relaunches. You aren't just launching the app, you are force-stopping it (and possibly replacing the APK) and then launching it. After WorkManager figures out it's been force-stopped, it makes sure to re-enqueue the tasks. This means periodic work will run again.
The reason they run when the app is launched is that you are effectively force-stopping your app by using Android Studio relaunches. You aren't just launching the app, you are force-stopping it (and possibly replacing the APK) and then launching it. After WorkManager figures out it's been force-stopped, it makes sure to re-enqueue the tasks. This means periodic work will run again.
Description
Version used: 1.0.0-alpha
Devices/Android versions reproduced on: Emulator API 27
PeriodicWork is rescheduled each time cold start.
So JobService will be registered as many times as cold start.
- Sample project to trigger the issue.
- Reproduction
1. Launch WorkManagerSample app
2. Push [SCHEDULE] button. (will scheduled the 15min interval Worker)
3. Exit app and Clear app history(from the ■ button)
4. Launch WorkManagerSample app again(cold start)
- Result of [>>adb shell dumpsys jobscheduler]. (scheduled 2 jobs...)
JOB #u0a80/4: c32b177 com.example.workmanagersample/androidx.work.impl.background.systemjob.SystemJobService
u0a80 tag=*job*/com.example.workmanagersample/androidx.work.impl.background.systemjob.SystemJobService
Source: uid=u0a80 user=0 pkg=com.example.workmanagersample
JobInfo:
Service: com.example.workmanagersample/androidx.work.impl.background.systemjob.SystemJobService
PERIODIC: interval=+15m0s0ms flex=+15m0s0ms
PERSISTED
Requires: charging=false batteryNotLow=false deviceIdle=false
Extras: {EXTRA_WORK_SPEC_ID=c46ef83e-13b1-4595-888e-b80a4c8a72cf, EXTRA_IS_PERIODIC=true}
Backoff: policy=1 initial=+30s0ms
Has early constraint
Has late constraint
Required constraints: TIMING_DELAY DEADLINE
Satisfied constraints: APP_NOT_IDLE DEVICE_NOT_DOZING
Unsatisfied constraints: TIMING_DELAY DEADLINE
Tracking: TIME
Enqueue time: -4m46s595ms
Run time: earliest=+10m7s569ms, latest=+25m7s569ms
Last successful run: 2018-05-14 04:49:01
Ready: false (job=false user=true !pending=true !active=true !backingup=true comp=true)
JOB #u0a80/5: 93cf1f3 com.example.workmanagersample/androidx.work.impl.background.systemjob.SystemJobService
u0a80 tag=*job*/com.example.workmanagersample/androidx.work.impl.background.systemjob.SystemJobService
Source: uid=u0a80 user=0 pkg=com.example.workmanagersample
JobInfo:
Service: com.example.workmanagersample/androidx.work.impl.background.systemjob.SystemJobService
PERIODIC: interval=+15m0s0ms flex=+15m0s0ms
PERSISTED
Requires: charging=false batteryNotLow=false deviceIdle=false
Extras: {EXTRA_WORK_SPEC_ID=c46ef83e-13b1-4595-888e-b80a4c8a72cf, EXTRA_IS_PERIODIC=true}
Backoff: policy=1 initial=+30s0ms
Has early constraint
Has late constraint
Required constraints: TIMING_DELAY DEADLINE
Satisfied constraints: APP_NOT_IDLE DEVICE_NOT_DOZING
Unsatisfied constraints: TIMING_DELAY DEADLINE
Tracking: TIME
Enqueue time: -2m12s405ms
Run time: earliest=+12m29s338ms, latest=+27m29s338ms
Last successful run: 2018-05-14 04:51:35
Ready: false (job=false user=true !pending=true !active=true !backingup=true comp=true)