2017-03-02 13 views
9

Właśnie rozpoczął naukę współprogram Kotlin i próbował symulować pewne dawno API połączeń z pokazując wynik na UI:Jak korzystać Kotlin współprogram czekają() na głównym wątku

class MainActivity : AppCompatActivity() { 
    fun log(msg: String) = println("[${Thread.currentThread().name}] $msg") 

    override 
    fun onCreate(savedInstanceState: Bundle?) { 
     super.onCreate(savedInstanceState) 
     this.setContentView(R.layout.activity_main) 
     val resultTV = findViewById(R.id.text) as TextView 

     val a = async(CommonPool) { 
      delay(1_000L) 
      6 
     } 

     val b = async(CommonPool) { 
      delay(1_000L) 
      7 
     } 

     launch(< NEED UI thread here >) { 
      val aVal = a.await() 
      val bVal = b.await() 
      resultTV.setText((aVal * bVal).toString()) 
     } 
    } 
} 

ja nie rozumiem, w jaki sposób mogę ewentualnie użyć metody launch z kontekstem .

Niestety, nie udało mi się znaleźć niczego na temat dostarczania wyników dla niektórych wątków pod numerem the official tutorial for coroutines.

+0

Niestety, gdzie znalazłeś 'metody launch'? –

+2

Może ta biblioteka pomoże ci https://github.com/metalabdesign/AsyncAwait –

+0

Chciałbym przez bibliotekę, ale martwiłem się tylko, że można to zrobić używając tylko standardowych kotlinx.coroutines. –

Odpowiedz

9

Edit:

zobaczyć również an official example in Kotlin repo

trzeba zaimplementować Continuation interfejs, który sprawia wywołania zwrotnego na wątku Android UI i Coroutine context

przykład (Od here)

private class AndroidContinuation<T>(val cont: Continuation<T>) : Continuation<T> by cont { 
    override fun resume(value: T) { 
     if (Looper.myLooper() == Looper.getMainLooper()) cont.resume(value) 
     else Handler(Looper.getMainLooper()).post { cont.resume(value) } 
    } 
    override fun resumeWithException(exception: Throwable) { 
     if (Looper.myLooper() == Looper.getMainLooper()) cont.resumeWithException(exception) 
     else Handler(Looper.getMainLooper()).post { cont.resumeWithException(exception) } 
    } 
} 

object Android : AbstractCoroutineContextElement(ContinuationInterceptor), ContinuationInterceptor { 
    override fun <T> interceptContinuation(continuation: Continuation<T>): Continuation<T> = 
     AndroidContinuation(continuation) 
} 

następnie spróbuj:

launch(Android) { 
    val aVal = a.await() 
    val bVal = b.await() 
    resultTV.setText((aVal * bVal).toString()) 
} 

więcej info:

https://medium.com/@macastiblancot/android-coroutines-getting-rid-of-runonuithread-and-callbacks-cleaner-thread-handling-and-more-234c0a9bd8eb#.r2buf5e6h

+0

Proszę odnieść się do oficjalnej biblioteki dla korporacji z Androidem -> https://github.com/gildor/kotlin-coroutines-android/blob/master/coroutines-android/README.md –

+0

Czy to od JetBrains czy od zespołu Android? Co masz na myśli przez oficjalne? – pt2121

+2

Przepraszamy, wkleiłem niewłaściwy link. Następujące osoby pochodzą z zespołu Kotlin, który zajmuje się obsługą korporacji w Androidzie https://github.com/Kotlin/kotlinx.coroutines/blob/master/ui/kotlinx-coroutines-android/src/main/kotlin/kotlinx/coroutines/experimental /android/HandlerContext.kt –

1

Przede wszystkim to prawo bibliotekę przeznaczoną dla Androida

build.gradle

apply plugin: 'kotlin-android' 
apply plugin: 'kotlin-android-extensions' 

android{ 
... 
    dependencies{ 
     ... 
     implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:0.19.3" 

    } 

    kotlin { 
    experimental { 
     coroutines "enable" 
    } 
    } 
} 

Następnie możesz używać UI

suspend private fun getFilteredGList(enumList: List<EnumXXX>) = mList.filter { 
    ... 
} 

private fun filter() { 
    val enumList = listOf(EnumX1, EnumX2) 
    launch(UI){ 
     val filteredList = getFilteredList(enumList) 
     setMarkersOnMap(filteredList) 
    } 

} 
Powiązane problemy