Fixed
Status Update
Comments
ru...@gmail.com <ru...@gmail.com> #2
Bringing setMaxSchedulerLimit to say 49 doesn't help. Same error.
ra...@google.com <ra...@google.com> #3
If you are using work-firebase then you should not be using JobScheduler directly. Can you please send us the full bug report so we can investigate ?
ru...@gmail.com <ru...@gmail.com> #4
java.lang.IllegalStateException: Apps may not schedule more than 100 distinct jobs
at android.os.Parcel.readException(Parcel.java:1692)
at android.os.Parcel.readException(Parcel.java:1637)
at android.app.job.IJobScheduler$Stub$Proxy.schedule(IJobScheduler.java:158)
at android.app.JobSchedulerImpl.schedule(JobSchedulerImpl.java:42)
at androidx.work.impl.background.systemjob.SystemJobScheduler.scheduleInternal(SystemJobScheduler.java:126)
at androidx.work.impl.background.systemjob.SystemJobScheduler.schedule(SystemJobScheduler.java:95)
at androidx.work.impl.Schedulers.scheduleInternal(Schedulers.java:104)
at androidx.work.impl.Schedulers.schedule(Schedulers.java:73)
at androidx.work.impl.WorkerWrapper.setSucceededAndNotify(WorkerWrapper.java:393)
at androidx.work.impl.WorkerWrapper.handleResult(WorkerWrapper.java:255)
at androidx.work.impl.WorkerWrapper.run(WorkerWrapper.java:181)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
at android.os.Parcel.readException(Parcel.java:1692)
at android.os.Parcel.readException(Parcel.java:1637)
at android.app.job.IJobScheduler$Stub$Proxy.schedule(IJobScheduler.java:158)
at android.app.JobSchedulerImpl.schedule(JobSchedulerImpl.java:42)
at androidx.work.impl.background.systemjob.SystemJobScheduler.scheduleInternal(SystemJobScheduler.java:126)
at androidx.work.impl.background.systemjob.SystemJobScheduler.schedule(SystemJobScheduler.java:95)
at androidx.work.impl.Schedulers.scheduleInternal(Schedulers.java:104)
at androidx.work.impl.Schedulers.schedule(Schedulers.java:73)
at androidx.work.impl.WorkerWrapper.setSucceededAndNotify(WorkerWrapper.java:393)
at androidx.work.impl.WorkerWrapper.handleResult(WorkerWrapper.java:255)
at androidx.work.impl.WorkerWrapper.run(WorkerWrapper.java:181)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
ru...@gmail.com <ru...@gmail.com> #5
What do you mean I shouldn't use JobScheduler directly? Isn't work-firebase is just for <21 devices, otherwise JobScheduler always used?
su...@google.com <su...@google.com> #6
I think i was confused by your previous comment. You are right, we only use work-firebase for API < 23.
JobScheduler is used for API >= 23.
This issue should have been resolved in `alpha03` and `alpha04` (we addressed different parts of the problem). If you can reproduce this on a device, then can you do:
1. adb shell dumpsys jobscheduler for your app.
2. Reboot your device.
3. After the reboot, can you re-run adb shell dumpsys jobscheduler ?
I want to check if you see any differences in the jobs created before and after the reboot.
Thanks for your patience.
JobScheduler is used for API >= 23.
This issue should have been resolved in `alpha03` and `alpha04` (we addressed different parts of the problem). If you can reproduce this on a device, then can you do:
1. adb shell dumpsys jobscheduler for your app.
2. Reboot your device.
3. After the reboot, can you re-run adb shell dumpsys jobscheduler ?
I want to check if you see any differences in the jobs created before and after the reboot.
Thanks for your patience.
ru...@gmail.com <ru...@gmail.com> #7
Actually for step 2, the easier thing to do is to force stop your app. You don't need to fo a full reboot.
ru...@gmail.com <ru...@gmail.com> #8
I don't have to to rummage through traces. Here's code snippet that sends app into a crash loop. https://pastebin.com/NcTAnwjZ
ra...@google.com <ra...@google.com> #9
I tried to reproduce this on alpha04. However, I cannot reproduce your issue.
For reference, this is what my activity looks like:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
findViewById<Button>(R.id.scheduler_limits_testcase1).setOnClickListener {
for (i in 1..100) {
val a1 = newWorkRequest("--- A1 ---")
val b1 = newWorkRequest("--- B1 ---")
val b2 = newWorkRequest("--- B2 ---")
val c1 = newWorkRequest("--- C1 ---")
WorkManager.getInstance()!!
.beginWith(a1).then(b1).enqueue()
WorkManager.getInstance()!!
.beginWith(a1).then(b2).enqueue()
WorkManager.getInstance()!!
.beginWith(b1, b2).then(c1).enqueue()
}
}
}
companion object {
private fun newWorkRequest(message: String): OneTimeWorkRequest {
val data = mapOf(TestWorker.KEY_MESSAGE to message).toWorkData()
return OneTimeWorkRequestBuilder<TestWorker>()
.setInputData(data)
.build()
}
}
}
This is what my Worker looks like:
class TestWorker : Worker() {
companion object {
private const val TAG = "TestWorker"
private const val MESSAGE_DEFAULT = "Default"
const val KEY_MESSAGE = "KEY_MESSAGE"
}
override fun doWork(): Result {
val message = inputData.getString(KEY_MESSAGE, MESSAGE_DEFAULT)
val random = Random()
val time = 500L + random.nextInt(300)
Log.d(TAG, "Before. $message")
Thread.sleep(time)
Log.d(TAG, "After. $message")
return Result.SUCCESS
}
}
For reference, this is what my activity looks like:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
findViewById<Button>(R.id.scheduler_limits_testcase1).setOnClickListener {
for (i in 1..100) {
val a1 = newWorkRequest("--- A1 ---")
val b1 = newWorkRequest("--- B1 ---")
val b2 = newWorkRequest("--- B2 ---")
val c1 = newWorkRequest("--- C1 ---")
WorkManager.getInstance()!!
.beginWith(a1).then(b1).enqueue()
WorkManager.getInstance()!!
.beginWith(a1).then(b2).enqueue()
WorkManager.getInstance()!!
.beginWith(b1, b2).then(c1).enqueue()
}
}
}
companion object {
private fun newWorkRequest(message: String): OneTimeWorkRequest {
val data = mapOf(TestWorker.KEY_MESSAGE to message).toWorkData()
return OneTimeWorkRequestBuilder<TestWorker>()
.setInputData(data)
.build()
}
}
}
This is what my Worker looks like:
class TestWorker : Worker() {
companion object {
private const val TAG = "TestWorker"
private const val MESSAGE_DEFAULT = "Default"
const val KEY_MESSAGE = "KEY_MESSAGE"
}
override fun doWork(): Result {
val message = inputData.getString(KEY_MESSAGE, MESSAGE_DEFAULT)
val random = Random()
val time = 500L + random.nextInt(300)
Log.d(TAG, "Before. $message")
Thread.sleep(time)
Log.d(TAG, "After. $message")
return Result.SUCCESS
}
}
ru...@gmail.com <ru...@gmail.com> #10
Do you have another part of your codebase that is scheduling jobs with JobScheduler?
ra...@google.com <ra...@google.com> #11
We have 1 job that schedules once on app start, that's it.
ra...@google.com <ra...@google.com> #12
I created a sample app.
For some reason it rarely crashes on AVD Emulator(Api 27), but 100% crashes on Genymotion Api 26 and my Xiaomi Redmi 7.1.2
You can try both Activities.
For some reason it rarely crashes on AVD Emulator(Api 27), but 100% crashes on Genymotion Api 26 and my Xiaomi Redmi 7.1.2
You can try both Activities.
ru...@gmail.com <ru...@gmail.com> #13
Hi, I've tried numerous times and have been unable to get your example to exhibit this problem. Could you please update to alpha05 and reproduce it? If you can reliably reproduce this issue, could you please do so with verbose logging enabled in your Configuration object (introduced in alpha05) and send us a bugreport?
ra...@google.com <ra...@google.com> #14
I will some time later when I have time
to...@gmail.com <to...@gmail.com> #15
Alpha 05, VERBOSE log level. Running the MainActivity in previous app.
su...@google.com <su...@google.com> #16
Hmm, there is a possibility based on your stacktrace that you are running into b/111801342 ; something about these particular devices/emulators is leading to the issue manifesting like this. This is fixed in alpha06 (which will be released later today). Please update later today to check.
ru...@gmail.com <ru...@gmail.com> #17
alpha 06, same thing
ra...@google.com <ra...@google.com>
to...@gmail.com <to...@gmail.com> #18
↑ This is Genymotion not Xiaomi log
ru...@gmail.com <ru...@gmail.com> #19
I tried to reproduce this on a Genymotion emulator as well (on alpha04 and alpha06) on API 26. I cannot seem to.
I am marking this as not reproducible.
I am marking this as not reproducible.
to...@gmail.com <to...@gmail.com> #20
You tried to reproduce it on my example above?
to...@gmail.com <to...@gmail.com> #21
How can you not reproduce it when I linked you the code to do so?
ra...@google.com <ra...@google.com> #22
Same issue for me, "java.lang.IllegalStateException: Apps may not schedule more than 100 distinct jobs", on Android 8.0.0 (HTC U11).
Just for my understanding, should we be able to enqueue more than ~100 WorkRequest ?
Just for my understanding, should we be able to enqueue more than ~100 WorkRequest ?
ra...@google.com <ra...@google.com> #23
Yes, you should. We found some edge cases where it's possible to schedule more work than allowable by the system and we're working on a fix. Thanks!
ru...@gmail.com <ru...@gmail.com> #25
A fix should be available in alpha07.
su...@google.com <su...@google.com> #26
I still got the 100 job crash once using alpha-07
Description
Version used: 1.0.0-beta1
Devices/Android versions reproduced on: API 19
This seems to be happening on API 19 only.
To reproduce, just add a Thread.sleep(1000) in any worker before returning Result.SUCCESS. Worker is stopped due to cancellation instead of being treated as being successful. This causes the worker to being retried.
In our case, the behavior is the same. We're using RxJava and blocking observable operators to perform network requests. This issue causes API 19 devices to keep running the same worker using the backoff strategy instead of marking it as success.
Sample project: