Fixed
Status Update
Comments
su...@google.com <su...@google.com> #2
One more detail here.
The body of navigateUp() method of NavController class (1.0.0-rc01) looks like this:
if (mBackStack.size() == 1) {
// If there's only one entry, then we've deep linked into a specific destination
// on another task so we need to find the parent and start our task from there
...
} else {
return popBackStack();
}
If I put a breakpoint on the very first line of that code and invoke this method anyhow, I can see that the size of mBackStack is actually 2 (with both root and child fragments).
So, the code doesn't consider the current case a deeplink case, but as a regular opening of the child destination.
The body of navigateUp() method of NavController class (1.0.0-rc01) looks like this:
if (mBackStack.size() == 1) {
// If there's only one entry, then we've deep linked into a specific destination
// on another task so we need to find the parent and start our task from there
...
} else {
return popBackStack();
}
If I put a breakpoint on the very first line of that code and invoke this method anyhow, I can see that the size of mBackStack is actually 2 (with both root and child fragments).
So, the code doesn't consider the current case a deeplink case, but as a regular opening of the child destination.
ra...@google.com <ra...@google.com> #4
Partially agree, but my case doesn't use nested graphs at all, so my issue is just simpler.
However, the actual problem seems to be the same: the library treats absence of Intent.FLAG_ACTIVITY_NEW_TASK as it is actually set, because all 'start destinations' are still added before the actual deeplink destination (as it is explained in the documentation where the flag is set).
However, the actual problem seems to be the same: the library treats absence of Intent.FLAG_ACTIVITY_NEW_TASK as it is actually set, because all 'start destinations' are still added before the actual deeplink destination (as it is explained in the documentation where the flag is set).
dr...@gmail.com <dr...@gmail.com> #5
This is a regression caused by https://android-review.googlesource.com/833717 where the NavGraph destinations would always be added to the back stack (it isn't both the root and child fragments, but the root graph and the child fragment) to avoid IllegalArgumentExceptions. Unfortunately, that broke the navigateUp() behavior, which is something we'll fix :)
ra...@google.com <ra...@google.com> #6
Project: platform/frameworks/support
Branch: androidx-master-dev
commit 781d0178da33d84f615b409b17975c8ba290401c
Author: Ian Lake <ilake@google.com>
Date: Mon Feb 25 15:38:23 2019
Fix navigateUp() logic when on another app's task
When using deep linking on another app's task,
only the final destination is created, ensuring that
hitting the system back button goes back to the
other app. The Up button, via navigateUp(), should
take users to your own task on the parent destination.
Recent changes made it so that we always add the
parent NavGraphs to the back stack, meaning the simple
check of back stack size == 1 does not properly handle
this change in behavior so instead we need to check for
the number of non-NavGraph destinations on the back
stack.
Test: new NavControllerActivityTest
BUG: 126082008
Change-Id: I7bf18d38e1cdd3818e7414ba44d84df0abd81b88
M navigation/runtime/src/androidTest/AndroidManifest.xml
A navigation/runtime/src/androidTest/java/androidx/navigation/NavControllerActivityTest.kt
M navigation/runtime/src/main/java/androidx/navigation/NavController.java
https://android-review.googlesource.com/912258
https://goto.google.com/android-sha1/781d0178da33d84f615b409b17975c8ba290401c
Branch: androidx-master-dev
commit 781d0178da33d84f615b409b17975c8ba290401c
Author: Ian Lake <ilake@google.com>
Date: Mon Feb 25 15:38:23 2019
Fix navigateUp() logic when on another app's task
When using deep linking on another app's task,
only the final destination is created, ensuring that
hitting the system back button goes back to the
other app. The Up button, via navigateUp(), should
take users to your own task on the parent destination.
Recent changes made it so that we always add the
parent NavGraphs to the back stack, meaning the simple
check of back stack size == 1 does not properly handle
this change in behavior so instead we need to check for
the number of non-NavGraph destinations on the back
stack.
Test: new NavControllerActivityTest
BUG: 126082008
Change-Id: I7bf18d38e1cdd3818e7414ba44d84df0abd81b88
M navigation/runtime/src/androidTest/AndroidManifest.xml
A navigation/runtime/src/androidTest/java/androidx/navigation/NavControllerActivityTest.kt
M navigation/runtime/src/main/java/androidx/navigation/NavController.java
dr...@gmail.com <dr...@gmail.com> #7
A fix will be available in Navigation 1.0.0-rc02. Thanks for reporting it and the great sample app!
ra...@google.com <ra...@google.com> #8
Thanks, Ian.
dr...@gmail.com <dr...@gmail.com> #9
Yeah sorry the OneTimeWorkRequest stuff was there as one way of getting the immediate work done, and mostly it's OK, but certainly for some devices in particular the device delays quite some time before running the work, so it's not immediate enough.
ra...@google.com <ra...@google.com> #10
We introduce some drift due to the way we reschedule ENQUEUED work on init (on process death).
I will fix this.
I will fix this.
ap...@google.com <ap...@google.com> #11
Project: platform/frameworks/support
Branch: androidx-master-dev
commit 39859499e6c1d1502f8dc764360b55a62eaba233
Author: Rahul Ravikumar <rahulrav@google.com>
Date: Mon Jun 17 16:28:19 2019
Fix for drifts in WorkRequests with periodStartTime = 0
* When we have WorkRequests with initial delays (and periodStartTime = 0)
and a process death occurs - we would previously look at all WorkSpecs
in ENQUEUED state and reschedule them.
* This would cause a drift for WorkSpecs with periodStartTime = 0,
because they would be scheduled relative to System.currentTimeInMillis().
* To fix this we move the cleanup step into ForceStopRunnable, given it is the
first Runnable being executed in the TaskExecutor. This way we can also
more accureately target WorkSpecs that were previously RUNNING rather than
having to reschedule all WorkSpecs that were ENQUEUED.
Fixes: b/135272196
Test: Existing unit tests in ForceStopRunnableTests, updated tests in WorkManagerImplTest.
Change-Id: I0fb5477c70a43b751fec1e0c5d9901188e2396f4
M work/workmanager/src/androidTest/java/androidx/work/impl/WorkManagerImplTest.java
M work/workmanager/src/androidTest/java/androidx/work/impl/utils/ForceStopRunnableTest.java
M work/workmanager/src/main/java/androidx/work/impl/WorkDatabase.java
M work/workmanager/src/main/java/androidx/work/impl/model/WorkSpecDao.java
M work/workmanager/src/main/java/androidx/work/impl/utils/ForceStopRunnable.java
https://android-review.googlesource.com/984508
https://goto.google.com/android-sha1/39859499e6c1d1502f8dc764360b55a62eaba233
Branch: androidx-master-dev
commit 39859499e6c1d1502f8dc764360b55a62eaba233
Author: Rahul Ravikumar <rahulrav@google.com>
Date: Mon Jun 17 16:28:19 2019
Fix for drifts in WorkRequests with periodStartTime = 0
* When we have WorkRequests with initial delays (and periodStartTime = 0)
and a process death occurs - we would previously look at all WorkSpecs
in ENQUEUED state and reschedule them.
* This would cause a drift for WorkSpecs with periodStartTime = 0,
because they would be scheduled relative to System.currentTimeInMillis().
* To fix this we move the cleanup step into ForceStopRunnable, given it is the
first Runnable being executed in the TaskExecutor. This way we can also
more accureately target WorkSpecs that were previously RUNNING rather than
having to reschedule all WorkSpecs that were ENQUEUED.
Fixes:
Test: Existing unit tests in ForceStopRunnableTests, updated tests in WorkManagerImplTest.
Change-Id: I0fb5477c70a43b751fec1e0c5d9901188e2396f4
M work/workmanager/src/androidTest/java/androidx/work/impl/WorkManagerImplTest.java
M work/workmanager/src/androidTest/java/androidx/work/impl/utils/ForceStopRunnableTest.java
M work/workmanager/src/main/java/androidx/work/impl/WorkDatabase.java
M work/workmanager/src/main/java/androidx/work/impl/model/WorkSpecDao.java
M work/workmanager/src/main/java/androidx/work/impl/utils/ForceStopRunnable.java
Description
When I set up a periodic job, I want the first in the series to be performed INSTANTLY (the user expects it... they hit a button and are waiting for an immediate result), and then for subsequent ones to be performed based on the periodic schedule (more vague timings is fine... the user is no longer waiting).
When you set up a periodic work request *without* a flex interval, it can run anytime in the set interval, i.e. from NOW until the end of the interval. If the device is awake when the periodic work request is scheduled, which is the case for me, I find that the first work in the series is generally performed at the START of the interval, i.e. NOW... though "NOW" may not be instantly (it's up to the device to decide... may be delayed a few seconds).
Because it cannot be guaranteed that the first periodic work will be performed *instantly*, instead I do an explicit call to the work-performing function outside of the WorkManager realm, and put a flexInterval on the periodic work of 5 mins so that the first periodic work will certainly not be performed straight away, but instead it will be near the end of the first period, most likely 5 mins before the end. This is not quite ideal (first gap between work runs is not quite a full interval) but it's OK... the user won't care or even notice it runs 5 mins "early" the first time.
Now, I thought that the ability to set an "initialDelay" in 2.1.0 would solve my problems... so that I could:
(a) still make an explicit call to the work-performing function to do the immediate work, guaranteed to be NOW (the user expects that)
(b) set up a periodic work request WITHOUT flexInterval (i.e. use the whole interval) and WITH an initial delay equal to the period "interval"
That way, I get the immediate work done, and then after "interval" the periodic work request is scheduled, and because (let's assume) the device is still awake, the first periodic work will likely perform at the START of the interval, i.e. almost straight away, i.e. pretty close to exactly one "interval" after the user set the schedule going.
BUT I'm not finding that. Let's say that "interval" of the periodic work is 15 mins, and I set an "initial delay" also of 15 mins, and I set this going when the user hits the button. I find that the immediate work is performed at 0 mins (triggered explicitly, not by WorkManager, so that's as expected), then at 15 mins NOTHING happens, and only at 30 mins does the first periodic work actually run.
It seems that either the first periodic work happens at the END of the first interval (15-30 mins) and not the start (like it usually does, if the device is awake and not busy), or WorkManager delayed first periodic interval to be at 30-45 mins, i.e. it waited 30 mins not 15 mins, twice what I asked for.
So, how is "setInitialDelay" for a periodic work request meant to work? It doesn't just wait "delay" (instead of not waiting at all) and then enqueue the periodic work request?