Home > Enterprise >  Getting a Value from the inside of a Coroutine outside of the Coroutine?
Getting a Value from the inside of a Coroutine outside of the Coroutine?

Time:07-14

I'm pretty new with kotlin programming and have to complete a tourguide project. I have a hopefully simple problem, but I'm too stupid to fix it, I guess.

In the following code segment I want to use the val "loc" (that's coming from the inside of a coroutine / addOnSuccessListener) as the "startlocation" that is currently set on "LatLng(49.7913, 9.9534)" outside the coroutine. But how do I get that value outside the main thread? Sadly, I can't just do "val startlocation = loc" :(

Please, does somebody have a simple fix for that? Thanks in advance!

override fun onMapReady(googleMap: GoogleMap) {
    mMap = googleMap
    val routenuebergabe = intent.getStringExtra("tourname").toString()
    Firebase.firestore.collection("Routen").document(routenuebergabe).get()
        .addOnCompleteListener { it ->
            if (it.isSuccessful) {
                CoroutineScope(Dispatchers.IO).launch {
                    val koors = it.await().get("starting_location").toString()
                    val strs = koors.split(",").toTypedArray()
                    val lat = strs[0].toDouble()
                    val lng = strs[1].toDouble()

                    Log.e("RoutendarstellungActivity", "Fatal $lat & $lng")
                    val loc = LatLng(lat, lng)
                }
            }
        }
    val startlocation = LatLng(49.7913, 9.9534)
    mMap.addMarker(MarkerOptions().position(startlocation).title("Marker in Würzburg"))
    mMap.moveCamera(CameraUpdateFactory.newLatLng(startlocation))
}

CodePudding user response:

Add to build.gradle (app):

    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.6.2'

Your code will look like this:

override fun onMapReady(googleMap: GoogleMap) = CoroutineScope(Dispatchers.IO).launch {
    try {
        mMap = googleMap

        val routenuebergabe = intent.getStringExtra("tourname").toString()
        val snapshot = Firebase.firestore.collection("Routen")
            .document(routenuebergabe)
            .get()
            .await()

        val koors = snapshot.get("starting_location").toString()
        val strs = koors.split(",").toTypedArray()
        val lat = strs[0].toDouble()
        val lng = strs[1].toDouble()

        val startlocation = LatLng(lat, lng)

        mMap.addMarker(MarkerOptions().position(startlocation).title("Marker in Würzburg"))
        mMap.moveCamera(CameraUpdateFactory.newLatLng(startlocation))
    } catch (e: Exception) {
        // Do something...
    }
}

You may need to wrap GoogleMap methods if they need to be called only from the UI thread:

withContext(Dispatchers.Main) {
    mMap.addMarker(MarkerOptions().position(startlocation).title("Marker in Würzburg"))
    mMap.moveCamera(CameraUpdateFactory.newLatLng(startlocation))
}
  • Related