android / android/architecture-samples

java.lang.IllegalStateException: Method addObserver must be called on the main thread

Open
#879 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Kotlin
Stars
45.8k
Forks
11.9k
PR merge metrics
No merged PRs in 30d

Description

Hello, I am trying to perform integration testing and use `launchFragmentInHiltContainer` to start my fragment for specific scenario. However I receive and error `java.lang.IllegalStateException: Method addObserver must be called on the main thread` on the `navController.setGraph(R.navigation.nav_graph)` line. Below I have provided my test class and the `launchFragmentInHiltContainer`.

```kotlin
@HiltAndroidTest
class SensorsTests {

@get:Rule
var hiltRule = HiltAndroidRule(this)

@Inject
lateinit var repository: MockRepositoryImpl

@BeforeAll
fun beforeAll() {
hiltRule.inject()
}

@Test
fun userSensorsAreVisible() {
val navController = TestNavHostController(ApplicationProvider.getApplicationContext())
navController.setGraph(R.navigation.nav_graph)

launchFragmentInHiltContainer(navHostController = navController)

Thread.sleep(10000)
}

}
```

```kotlin
inline fun launchFragmentInHiltContainer(
fragmentArgs: Bundle? = null,
@StyleRes themeResId: Int = R.style.Theme_SensorsTracker,
navHostController: NavHostController? = null,
crossinline action: Fragment.() -> Unit = {}
) {
val startActivityIntent = Intent.makeMainActivity(
ComponentName(
ApplicationProvider.getApplicationContext(),
HiltTestActivity::class.java
)
).putExtra(
"androidx.fragment.app.testing.FragmentScenario.EmptyFragmentActivity.THEME_EXTRAS_BUNDLE_KEY",
themeResId
)

ActivityScenario.launch(startActivityIntent).onActivity { activity ->
val fragment: Fragment = activity.supportFragmentManager.fragmentFactory.instantiate(
Preconditions.checkNotNull(T::class.java.classLoader),
T::class.java.name
)

fragment.arguments = fragmentArgs

fragment.viewLifecycleOwnerLiveData.observeForever { viewLifecycleOwner ->
if (viewLifecycleOwner != null) {
navHostController?.let {
Navigation.setViewNavController(fragment.requireView(), it)
}
}
}

activity.supportFragmentManager
.beginTransaction()
.add(android.R.id.content, fragment, "")
.commitNow()

fragment.action()
}
}
```

Contributor guide

Open the contributing guide

Research direction

Start with SensorsTests.userSensorsAreVisible and the launchFragmentInHiltContainer helper, especially ActivityScenario.onActivity and the navController.setGraph call. Reproduce the integration test and trace the reported main-thread exception; done is a documented, reproducible resolution that lets the scenario run without it.

Written by the indexing model from the issue text.

Assessment

Tech stack
android, kotlin
Domain
mobile-dev, testing
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.