Edit module build.gradle
.
dependencies {
// https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md
def kotlin_version = '1.3.11'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
// https://mvnrepository.com/artifact/org.jetbrains.kotlinx/kotlinx-coroutines-android
// implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:0.24.0'
// implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:0.27.0-eap13'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.0'
}
Edit gradle.properties
to remove kotlin.coroutines=enable
.
# kotlin.coroutines=enable
Change import from
import kotlinx.coroutines.experimental.android.UIimport kotlinx.coroutines.experimental.launch
to
import kotlinx.coroutines.Dispatchersimport kotlinx.coroutines.GlobalScope
Replace code
launch(UI) {}launch(CommonPool) {}
to
// Main/UI ThreadGlobalScope.launch(Dispatchers.Main) {}// Background ThreadGlobalScope.launch(Dispatchers.Default) { // or Dispatchers.IO}
CoroutineScope should be implemented on entities with well-defined lifecycle that are responsible for launching children coroutines. Example of such entity on Android is Activity.
class MyActivity : AppCompatActivity(), CoroutineScope { lateinit var job: Job override val coroutineContext: CoroutineContext get() = Dispatchers.Main + job override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) job = Job() } override fun onDestroy() { super.onDestroy() job.cancel() // Cancel job on activity destroy. After destroy all children jobs will be cancelled automatically } /* * Note how coroutine builders are scoped: if activity is destroyed or any of the launched coroutines * in this method throws an exception, then all nested coroutines are cancelled. */ fun loadDataFromUI() = launch { // <- extension on current activity, launched in the main thread val ioData = async(Dispatchers.IO) { // <- extension on launch scope, launched in IO dispatcher // blocking I/O operation } // do something else concurrently with I/O val data = ioData.await() // wait for result of I/O draw(data) // can draw in the main thread } }}
NOTE: Refer to latest CoroutineScope implementation.
NOTE: For ViewModel CoroutineScope, cancel the job at onCleared
.
If you are using retrofit2 kotlin coroutine adapter, you will bump into the following error.
java.lang.NoClassDefFoundError: Failed resolution of: Lkotlinx/coroutines/experimental/Deferred;
at com.jakewharton.retrofit2.adapter.kotlin.coroutines.experimental.CoroutineCallAdapterFactory.get(CoroutineCallAdapterFactory.kt:59)
Replace the dependencies
// implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-experimental-adapter:1.0.0'
implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2'
References: