I haven’t traced the threads all the way through, but I worry about making the recursive call by continuing to launch new coroutines.
My solution is similar, but puts a loop inside the launch() routine instead of the recursive call back to the function.
private fun fetchCharacterFromAPIAsync() = CoroutineScope(Dispatchers.Main).launch {
try {
// display the "Generating Character" message while blocking call executes
characterData = CharacterGenerator.placeHolderCharacter()
displayCharacterData()
do {
// fetchCharacterData() is a suspend function - it is a blocking call
characterData = fetchCharacterDataBlocking() // perform the API call
// code will continue when blocking call completes
} while (characterData.str.toInt() < 10)
Log.d(LOG_TAG, "fetchCharacterFromAPIAsync() received valid character")
// display the network queried character
displayCharacterData()
} finally {
Log.d(LOG_TAG, "fetchCharacterFromAPIAsync() finally block")
}
}
private suspend fun fetchCharacterDataBlocking() = withContext(Dispatchers.IO) {
val apiData = URL(CHARACTER_DATA_API).readText()
CharacterGenerator.fromApiData(apiData)
}