Fixed
Status Update
Comments
su...@google.com <su...@google.com> #2
We introduced a regression in beta02. Can you try using beta01 instead ?
ap...@google.com <ap...@google.com> #3
Also, beta03 is coming with a fix very soon.
ra...@google.com <ra...@google.com>
li...@pinterest.com <li...@pinterest.com> #4
Thank you for your prompt response. I've checked the functioning of OneTimeWorkRequest in beta01 and it works as expected. Looking forward to beta03 for the fix.
su...@google.com <su...@google.com> #5
beta03 is out.
li...@pinterest.com <li...@pinterest.com> #6
In beta03, the bug seems fixed when JobScheduler backend is used.
But the bug seems to remain when AlarmManager backend is used.
The following step-by-step fails for me on emulator "Nexus 7 (2012) API 22", but passes on emulator "Pixel 2 XL API 27".
STEP BY STEP:
1. Create a "Hello world" Android app using Android Studio wizard and add implementation("android.arch.work:work-runtime:1.0.0-beta03") to dependencies
2. Add the following to MainActivity.onCreate():
final String name = Long.toString(System.currentTimeMillis()); // To ensure fresh name each run
final OneTimeWorkRequest workRequest = new OneTimeWorkRequest.Builder(LogPrinter.class)
.setBackoffCriteria(BackoffPolicy.LINEAR, WorkRequest.MIN_BACKOFF_MILLIS, TimeUnit.MILLISECONDS)
.addTag(name)
.build();
Log.e("Repro", "Calling enqueueUniqueWork(" + name + ", ...)");
WorkManager.getInstance().enqueueUniqueWork(name, ExistingWorkPolicy.REPLACE, workRequest);
where LogPrinter.class doWork() is:
@NonNull
@Override
public Result doWork() {
Log.e("Repro", "doWork() called. Now swipe away app in App Switcher. Tags: " + getTags());
SystemClock.sleep(10000);
Log.e("Repro", "Too late, try again. Tags: " + getTags());
return Result.success();
}
3. Run the app and check adb logcat -s Repro
4. When you see "Now swipe away app in App Switcher", do that.
EXPECTED:
You should see "doWork() called ..." again after max 10 seconds (due to specified backoff time), since the WorkManager framework should ensure that the Worker that never was finished gets a chance to run again.
ACTUAL:
On API 22, you never see "doWork() called ..." again (Test fails).
On API 27, you do see "doWork() called ..." again (Test pass).
Let me know if you need more input.
Best regards,
Martin Nordholts
But the bug seems to remain when AlarmManager backend is used.
The following step-by-step fails for me on emulator "Nexus 7 (2012) API 22", but passes on emulator "Pixel 2 XL API 27".
STEP BY STEP:
1. Create a "Hello world" Android app using Android Studio wizard and add implementation("android.arch.work:work-runtime:1.0.0-beta03") to dependencies
2. Add the following to MainActivity.onCreate():
final String name = Long.toString(System.currentTimeMillis()); // To ensure fresh name each run
final OneTimeWorkRequest workRequest = new OneTimeWorkRequest.Builder(LogPrinter.class)
.setBackoffCriteria(BackoffPolicy.LINEAR, WorkRequest.MIN_BACKOFF_MILLIS, TimeUnit.MILLISECONDS)
.addTag(name)
.build();
Log.e("Repro", "Calling enqueueUniqueWork(" + name + ", ...)");
WorkManager.getInstance().enqueueUniqueWork(name, ExistingWorkPolicy.REPLACE, workRequest);
where LogPrinter.class doWork() is:
@NonNull
@Override
public Result doWork() {
Log.e("Repro", "doWork() called. Now swipe away app in App Switcher. Tags: " + getTags());
SystemClock.sleep(10000);
Log.e("Repro", "Too late, try again. Tags: " + getTags());
return Result.success();
}
3. Run the app and check adb logcat -s Repro
4. When you see "Now swipe away app in App Switcher", do that.
EXPECTED:
You should see "doWork() called ..." again after max 10 seconds (due to specified backoff time), since the WorkManager framework should ensure that the Worker that never was finished gets a chance to run again.
ACTUAL:
On API 22, you never see "doWork() called ..." again (Test fails).
On API 27, you do see "doWork() called ..." again (Test pass).
Let me know if you need more input.
Best regards,
Martin Nordholts
cr...@gmail.com <cr...@gmail.com> #7
When a swipe to dismiss happens you should see a message in logcat which looks like:
W/ActivityManager( 1532): Scheduling restart of crashed service androidx.work.integration.testapp/androidx.work.impl.background.systemalarm.SystemAlarmService in 47470ms
Service crashes are different from Worker retries or backoffs. So you won't see it in 10 seconds. It might take longer. Look at the logs for more info.
W/ActivityManager( 1532): Scheduling restart of crashed service androidx.work.integration.testapp/androidx.work.impl.background.systemalarm.SystemAlarmService in 47470ms
Service crashes are different from Worker retries or backoffs. So you won't see it in 10 seconds. It might take longer. Look at the logs for more info.
Description
Version used: 1.0.0-beta05
Devices/Android versions reproduced on: all devices
The context of this ticket is to support initializing WorkManager a bit later after the application cold start in order to keep cold start fast. I am aware that:
1. WorkManager has this auto-initialization support through the WorkManagerInitializer provider.
2. It can be disabled and replaced by a custom provider to call WorkManager.initialize() directly or call it from Application.onCreate().
3. A number of services and receivers are registered by WorkManager and they rely on the early initialization of the WorkManager.
During testing, I realized the WorkManager.initialize() spends non-trivial time, it could be 50ms on some low end devices. So I want to avoid that delay during the cold start and have an option to initialize WorkManager a bit later. The request is to add code into the receivers and services to initialize WorkManager by themselves if WorkManager has not been initialized. This will help to cover the time from the application startup to the time that the application initialize the WorkManager manually.
Currently, a crash will happen in those receivers and services if they are triggered before the WorkManager is initialized in the application.
03-04 22:35:15.552 5784-5784/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.pinterest, PID: 5784
java.lang.RuntimeException: Unable to create service androidx.work.impl.background.systemjob.SystemJobService: java.lang.IllegalStateException: WorkManager needs to be initialized via a ContentProvider#onCreate() or an Application#onCreate().
at android.app.ActivityThread.handleCreateService(ActivityThread.java:3172)
at android.app.ActivityThread.-wrap5(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1550)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
Caused by: java.lang.IllegalStateException: WorkManager needs to be initialized via a ContentProvider#onCreate() or an Application#onCreate().
at androidx.work.impl.background.systemjob.SystemJobService.onCreate(SystemJobService.java:68)
at android.app.ActivityThread.handleCreateService(ActivityThread.java:3162)
at android.app.ActivityThread.-wrap5(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1550)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)