Home > Net >  Kotlin Why can't I change my variables in my onCompleteListener
Kotlin Why can't I change my variables in my onCompleteListener

Time:04-26

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

  • Related