I'm trying to make an android google maps app and I'm having trouble with the global variables I assign values to inside the listener not being completed. In this case, I'm trying to store the current location of the device after setting a marker there, and the documentation said to use a listener. The problem is, the values reset to their previous values after the listener is complete, and I can't return from inside the listener.
Here's the variable, it's not private right now because I was testing if it affected it for some reason:
lateinit var latLng : LatLng
Here's the function causing the problems:
private fun setDestinations() : LatLng{
checkPermission()
var locationResult = fusedLocationProviderClient.lastLocation;
var lat = 0.0
var lng = 0.0
locationResult.addOnCompleteListener(this) { task ->
if(task.isSuccessful){
lng = locationResult.result.longitude
lat = locationResult.result.latitude
latLng = LatLng(lat, lng)
setBaseLocation(lat, lng)
/**debug**/
println("First: $lat $lng")
} else {
Toast.makeText(this, "Cannot retrieve location", Toast.LENGTH_LONG).show()
}
}
println("Third: " latLng.latitude " " latLng.latitude)
return latLng
}
I get thrown an error when it reaches return saying that latLng
has not been initialized
please help me if you can, I really need it
CodePudding user response:
In your code locationResult.addOnCompleteListener(this) { task -> }
is an async callback and it will return the result once the async task (fetching the location) is done.
Meanwhile your rest of the code outside this callback is called synchronously, So it returns the latlng while the addOnCompleteListener
callback is still waiting for a result.
That causes the "latLng has not been initialized"
More about synchronous and asynchronous executions : Asynchronous vs synchronous execution, what is the main difference?
CodePudding user response:
you sure this line
println("Third: " latLng.latitude " " latLng.latitude)
is not throwing the error?
Cause this line also using latLng.
As of an asynchronous callback,the latLng is not initialized before the synchronous return is executed. And that's why you should get error in the print line.
CodePudding user response:
That's because this part is not called when the function returns.
locationResult.addOnCompleteListener(this) { task ->
if(task.isSuccessful){
lng = locationResult.result.longitude
lat = locationResult.result.latitude
latLng = LatLng(lat, lng)
setBaseLocation(lat, lng)
/**debug**/
println("First: $lat $lng")
} else {
Toast.makeText(this, "Cannot retrieve location", Toast.LENGTH_LONG).show()
}
}
So, your method is like
private fun setDestinations() : LatLng{
checkPermission()
return latLng
}
You should avoid return or you need to make sure if the variable is initialized before it returns. Maybe you can try with coroutine(ex. runBlocking and join).