Bug P4
Status Update
Comments
ae...@google.com <ae...@google.com> #2
Do you have a repro project that you could share with us?
There should be no need to excluding any dependencies: we automatically remove them from the test APK if they are in the main APK.
There should be no need to excluding any dependencies: we automatically remove them from the test APK if they are in the main APK.
Description
I have been running into the following error while implementing tests using ActivityScenario :
Activity never becomes requested state "[CREATED, DESTROYED, STARTED, RESUMED]" (last lifecycle transition = "CREATED")
After some digging, i came to understand to root cause of this issue.
The error is generated in the following method, in ActivityScenario.java:
/**
* Blocks the current thread until activity transition completes and its state becomes one of a
* given state.
*/
private void waitForActivityToBecomeAnyOf(State... expectedStates) {
// Wait for idle sync otherwise we might hit transient state.
getInstrumentation().waitForIdleSync();
Set<State> expectedStateSet = new HashSet<>(Arrays.asList(expectedStates));
lock.lock();
try {
if (expectedStateSet.contains(STEADY_STATES.get(currentActivityStage))) {
return;
}
long now = System.currentTimeMillis();
long deadline = now + TIMEOUT_MILLISECONDS;
while (now < deadline
&& !expectedStateSet.contains(STEADY_STATES.get(currentActivityStage))) {
stateChangedCondition.await(deadline - now, TimeUnit.MILLISECONDS);
now = System.currentTimeMillis();
}
if (!expectedStateSet.contains(STEADY_STATES.get(currentActivityStage))) {
throw new AssertionError(
String.format(
"Activity never becomes requested state \"%s\" (last lifecycle transition ="
+ " \"%s\")",
expectedStateSet, currentActivityStage));
}
} catch (InterruptedException e) {
throw new AssertionError(
String.format(
"Activity never becomes requested state \"%s\" (last lifecycle transition = \"%s\")",
expectedStateSet, currentActivityStage),
e);
} finally {
lock.unlock();
}
}
So what this method does, is that it waits for a certain amount of time (TIMEOUT_MILLISECONDS) for the activity lifecycle transitions to happen. While my tests are running, the system clock gets updated to a value in the past (Which is a legit scenario for my use case), which causes System.currentTimeMillis() to return a value very different from long deadline = now + TIMEOUT_MILLISECONDS, which leads to the exception.
My recommendation here would be to rather than relying on System.currentTimeMillis(), to use SystemClock.elapsedRealTime(), which does returns the time elapsed since the last boot of the device.
With this change, updating the system time would not affect anymore the implementation and the issue should be sorted out.
Please let me know about your feedback,
Best regards,
Mouad Errafay