Advitiay Anand
06/13/2022, 3:22 PMlistOfRides.map { ... }
freezes the app?
private fun initUserAndRides() {
// TODO: Fix this
viewModelScope.launch {
val userInstance = repository.getUser()
val listOfRides =
repository.getRides()
_user.postValue(userInstance)
withContext(Dispatchers.Default) {
val listOfUserRides = listOfRides.map { UserRide.createUserRide(userInstance, it) }
_rides.postValue(listOfUserRides)
}
}
}
Please know that UserRide.createUserRide(userInstance, it)
is computationally-expensive.
Also, repository.getUser()
and repository.getRides()
are suspend functions implemented by Retrofit.Sergio C.
06/13/2022, 8:41 PMAdvitiay Anand
06/14/2022, 3:34 AMAdvitiay Anand
06/14/2022, 3:02 PMinit {}
, I'm fetching that data, mapping it to get the processed data, then setting this processed data to a LiveData's value.
• The problem is the mapping... Each data element requires binary search to get mapped properly, and somehow that stops the coroutine without any error.Advitiay Anand
06/14/2022, 3:09 PMinit {
initUserAndRides()
}
private fun initUserAndRides() {
viewModelScope.launch {
val userInstance = repository.getUser()
val listOfRides =
repository.getRides()
val listOfUserRides = mapRidesToUserRides(listOfRides, userInstance)
_user.value = userInstance
_rides.value = listOfUserRides
}
}
private suspend fun mapRidesToUserRides(listOfRides: List<Ride>, user: User): List<UserRide> {
return withContext(Dispatchers.Default) {
listOfRides.map { UserRide.createUserRide(user, it) }
}
}
UserRide
// TODO: computeDistance freezes screen
fun createUserRide(user: User, ride: Ride): UserRide {
return UserRide(
user = user,
ride = ride,
date = processDate(ride.date),
distance = computeDistance(user.station_code, ride.station_path)
)
}
fun computeDistance(userStationCode: Int, stationPath: List<Int>): Int {
val closestStationCode = findClosest(userStationCode, stationPath)
return abs(closestStationCode - userStationCode)
}
private fun findClosest(userStationCode: Int, stationPath: List<Int>): Int {
if (userStationCode <= stationPath.first()) {
return stationPath.first()
}
if (userStationCode >= stationPath.last()) {
return stationPath.last()
}
if (stationPath.size > 2) {
// Binary Search
var low = 0
var high = stationPath.lastIndex
while (low + 1 < high) {
val mid = low + (high - 1) / 2
if (stationPath[mid] == userStationCode) {
return stationPath[mid]
}
if (stationPath[mid] > userStationCode) {
high = mid
} else {
low = mid
}
}
// Post processing
return if (abs(stationPath[low] - userStationCode) < abs(stationPath[high] - userStationCode))
stationPath[low]
else stationPath[high]
}
// Linear Search
return if (abs(stationPath[0] - userStationCode) < abs(stationPath[1] - userStationCode))
stationPath[0]
else stationPath[1]
}