Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

App slow after making a request inside another request

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

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

 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)
            }
        }

>Solution :

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)
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading