I have the follow error when I use ShowCaseView:
java.lang.IllegalStateException: Iteration already started
at android.view.ViewTreeObserver$CopyOnWriteArray.start(ViewTreeObserver.java:1157)
at android.view.ViewTreeObserver.dispatchOnGlobalLayout(ViewTreeObserver.java:941)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2250)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1392)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6752)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at org.robolectric.shadows.ShadowMessageQueue.dispatchMessage(ShadowMessageQueue.java:141)
at org.robolectric.shadows.ShadowMessageQueue.access$100(ShadowMessageQueue.java:32)
at org.robolectric.shadows.ShadowMessageQueue$1.run(ShadowMessageQueue.java:120)
at org.robolectric.util.Scheduler$ScheduledRunnable.run(Scheduler.java:362)
at org.robolectric.util.Scheduler.runOneTask(Scheduler.java:261)
at org.robolectric.util.Scheduler.advanceTo(Scheduler.java:242)
at org.robolectric.util.Scheduler.advanceBy(Scheduler.java:225)
at org.robolectric.util.Scheduler.advanceBy(Scheduler.java:215)
at org.robolectric.util.Scheduler.setIdleState(Scheduler.java:82)
at org.robolectric.util.Scheduler.unPause(Scheduler.java:117)
at org.robolectric.shadows.ShadowLooper.unPause(ShadowLooper.java:310)
at org.robolectric.shadows.ShadowLooper.runPaused(ShadowLooper.java:361)
at org.robolectric.shadows.ShadowViewGroup.addView(ShadowViewGroup.java:30)
at android.view.ViewGroup.addView(ViewGroup.java)
at android.view.ViewGroup.addView(ViewGroup.java:4708)
at android.view.ViewGroup.addView(ViewGroup.java:4681)
at ru.dimorinny.showcasecard.ShowCaseView.show(ShowCaseView.java:377)
at ru.dimorinny.showcasecard.ShowCaseView$1$1.onMeasured(ShowCaseView.java:293)
at ru.dimorinny.showcasecard.util.MeasuredUtils$2.onMeasured(MeasuredUtils.java:40)
at ru.dimorinny.showcasecard.util.MeasuredUtils.afterOrAlreadyMeasured(MeasuredUtils.java:49)
at ru.dimorinny.showcasecard.util.MeasuredUtils.afterOrAlreadyMeasuredViews(MeasuredUtils.java:35)
at ru.dimorinny.showcasecard.ShowCaseView$1.onMeasured(ShowCaseView.java:286)
at ru.dimorinny.showcasecard.util.MeasuredUtils$3.onMeasured(MeasuredUtils.java:54)
at ru.dimorinny.showcasecard.util.MeasuredUtils$1.onGlobalLayout(MeasuredUtils.java:21)
at android.view.ViewTreeObserver.dispatchOnGlobalLayout(ViewTreeObserver.java:945)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2250)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1392)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6752)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at org.robolectric.shadows.ShadowMessageQueue.dispatchMessage(ShadowMessageQueue.java:141)
at org.robolectric.shadows.ShadowMessageQueue.access$100(ShadowMessageQueue.java:32)
at org.robolectric.shadows.ShadowMessageQueue$1.run(ShadowMessageQueue.java:120)
at org.robolectric.util.Scheduler$ScheduledRunnable.run(Scheduler.java:362)
at org.robolectric.util.Scheduler.runOneTask(Scheduler.java:261)
at org.robolectric.util.Scheduler.advanceTo(Scheduler.java:242)
at org.robolectric.util.Scheduler.advanceBy(Scheduler.java:225)
at org.robolectric.util.Scheduler.advanceBy(Scheduler.java:215)
at org.robolectric.util.Scheduler.runOrQueueRunnable(Scheduler.java:334)
at org.robolectric.util.Scheduler.postDelayed(Scheduler.java:156)
at org.robolectric.util.Scheduler.postDelayed(Scheduler.java:145)
at org.robolectric.shadows.ShadowMessageQueue.enqueueMessage(ShadowMessageQueue.java:127)
at android.os.MessageQueue.enqueueMessage(MessageQueue.java)
at android.os.Handler.enqueueMessage(Handler.java:662)
at android.os.Handler.sendMessageAtTime(Handler.java:631)
at android.view.ViewRootImpl$ViewRootHandler.sendMessageAtTime(ViewRootImpl.java:3728)
at android.os.Handler.sendMessageDelayed(Handler.java:601)
at android.os.Handler.sendMessage(Handler.java:538)
at android.view.ViewRootImpl.dispatchResized(ViewRootImpl.java:6451)
at org.robolectric.util.ReflectionHelpers.callInstanceMethod(ReflectionHelpers.java:249)
at org.robolectric.shadows.ShadowViewRootImpl.callDispatchResized(ShadowViewRootImpl.java:101)
at org.robolectric.android.controller.ActivityController.visible(ActivityController.java:125)
at com.valderas.leonardo.adefulproject.activity.NavigationBottomActivityTest.setUp(NavigationBottomActivityTest.kt:35)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.robolectric.internal.SandboxTestRunner$2.evaluate(SandboxTestRunner.java:253)
at org.robolectric.internal.SandboxTestRunner.runChild(SandboxTestRunner.java:130)
at org.robolectric.internal.SandboxTestRunner.runChild(SandboxTestRunner.java:42)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.robolectric.internal.SandboxTestRunner$1.evaluate(SandboxTestRunner.java:84)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
at com.intellij.rt.execution.application.AppMainV2.main(AppMainV2.java:131)
Method in my activity:
private fun validateShowCase(){
if (viewModel.validateIfShowCaseViewShouldBeShown()) {
ShowCaseView.Builder(this)
.withTypedPosition(
ViewPosition(fabMain)
)
.withContent(
getString(R.string.showcase_information_menu)
)
.build()
.show(this)
viewModel.showCaseViewShowed()
}
Test Class
@RunWith(RobolectricTestRunner::class)
@Config(constants = BuildConfig::class,
sdk = [27],
application = Application::class)
class NavigationBottomActivityTest : BaseTest() {
private lateinit var controller: ActivityController<NavigationBottomActivity>
private lateinit var activity: NavigationBottomActivity
private lateinit var shadowActivity: ShadowActivity
private lateinit var menuTournamentModel: MenuTournamentModel
override fun setUp() {
super.setUp()
controller = Robolectric.buildActivity(NavigationBottomActivity::class.java).create().visible() // error here
activity = controller.get()
shadowActivity = Shadows.shadowOf(activity)
}
robolectricTest = '3.8'
compileSdkVersion = 27
minSdkVersion = 18
targetSdkVersion = 27
Likely related to the scheduler being IdleState.UNPAUSED...
Also hitting this in 4.0.2
Repro project: https://github.com/chrisbanes/tivi/tree/cb/robolectric-app-tests
Test: https://github.com/chrisbanes/tivi/blob/cb/robolectric-app-tests/app/src/test/java/app/tivi/HomeActivityNavigationTests.kt
Calling Robolectric.getForegroundThreadScheduler().pause(); solved this issue in my tests. I called that in my setup method.
We've done a complete rewrite of Robolectric's threading model, available to try now in 4.3-beta-1 that we hope will fix many issues with the legacy scheduler.
Please give it a try by annotating your test with @LooperMode(PAUSED).
Please reopen this issue if you continue to see problems.
Most helpful comment
We've done a complete rewrite of Robolectric's threading model, available to try now in 4.3-beta-1 that we hope will fix many issues with the legacy scheduler.
Please give it a try by annotating your test with @LooperMode(PAUSED).
Please reopen this issue if you continue to see problems.