I am making a request with coroutines based on a user name, which returns a list of Object<Profile>
, and with that list I am making another request with each object, and then switching and passing the info to another screen, but such process is making the app super slow and I would like to find a better way or a way to not making this process so slow. Here my code
Fragment from where I am starting the process and where the app is getting super slow
emptyHomeViewModel.getPlayersListByName(text)
emptyHomeViewModel.listOfPlayersByNameLiveData.observe(viewLifecycleOwner) { playersByName ->
emptyHomeViewModel.getPlayersProfileByName(playersByName)
emptyHomeViewModel.listOfProfilesByID.observe(viewLifecycleOwner) { profiles ->
if (profiles != null) {
val list: Array<Profile> = profiles.toTypedArray()
bundle = Bundle().apply {
putSerializable("user", list)
}
findNavController().navigate(
R.id.action_emptyHomeFragment_to_selectUserFragment,
bundle
)
}
}
}
ViewModel from where I am executing the coroutines and making the request to the API
fun getPlayersListByName(playerName: String) = viewModelScope.launch {
val playersList = getPlayersByPersonaNameUseCase.getPlayersByName(playerName)
if (playersList != null) {
_listOfPlayersByNameLiveData.postValue(playersList)
}
}
fun getPlayersProfileByName(playersByName: List<PlayerByPersonaNameItem>?) =
viewModelScope.launch {
var playersProfileList: ArrayList<Profile> = arrayListOf()
if (playersByName != null) {
for (player in playersByName) {
getPlayerByIDUseCase.getPlayerById(player.accountId)
?.let { playersProfileList.add(it) }
}
_listOfProfilesByID.postValue(playersProfileList)
}
}
CodePudding user response:
You can actually load profiles in parallel, preventing loading them one after another, to decrease time of loading data:
fun getPlayersProfileByName(playersByName: List<PlayerByPersonaNameItem>?) =
viewModelScope.launch {
val playersProfileList: List<Profile> = playersByName?.map { player ->
async {
getPlayerByIDUseCase.getPlayerById(player.accountId)
}
}.awaitAll().filterNotNull()
_listOfProfilesByID.postValue(playersProfileList)
}
Also you can improve it a little bit by removing additional LiveData
observer and calling getPlayersProfileByName
right after you get playersList
:
fun getPlayersListByName(playerName: String) = viewModelScope.launch {
val playersList = getPlayersByPersonaNameUseCase.getPlayersByName(playerName)
getPlayersProfileByName(playersList)
}