13

What should I change in my build.gradle file or import in classes to use stable coroutine functions in my Android project with Kotlin 1.3 ?

Fragment about coroutines in my build.gradle

implementation "org.jetbrains.kotlin:kotlin-coroutines-core:$coroutines_version" implementation "org.jetbrains.kotlin:kotlin-coroutines-android:$coroutines_version"

Of course I use Android Studio 3.3 Preview

Patryk Kubiak
  • 1,679
  • 2
  • 11
  • 17
  • Kotlin 1.3 is not release yet. You have to use EAP, if you want Kotlin 1.3 – Joshua Oct 25 '18 at 04:11
  • I' am using it, but I think I do not migrate to Kotlin 1.3 correctly. I have an error on my implementation of coroutine libraries in gradle "`library should be updated to be compatible with kotlin 1.3`" – Patryk Kubiak Oct 25 '18 at 04:59
  • I can't find any info what version is properly. – Patryk Kubiak Oct 25 '18 at 05:00
  • Add `http://dl.bintray.com/kotlin/kotlin-eap`. Current Kotlin is `1.3.0-rc-190`. Make sure you update Kotlin plugin as well. Also, it is `org.jetbrains.kotlinx:kotlinx-coroutines-core` and `org.jetbrains.kotlinx:kotlinx-coroutines-android` – Joshua Oct 25 '18 at 05:35
  • Thanks Joshua for response! My teammate helped me to find the solution. I had to increase the coroutines version to 1.0.0-RC1 – Patryk Kubiak Oct 25 '18 at 06:02
  • @Joshua Your info is already outdated, the RC version is on Maven Central. – Marko Topolnik Oct 25 '18 at 06:27

4 Answers4

28

In build.gradle change a library to

implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.1'.

Remove, if was added:

kotlin {
    experimental {
        coroutines "enable"
    }
}

In code change launch to GlobalScope.launch(Dispatchers.IO) or GlobalScope.launch(Dispatchers.Main).

UPDATE

Please, use local coroutine context instead of global scope (see, for instance, http://kotlinlang.org/docs/reference/coroutines/coroutine-context-and-dispatchers.html).

For Activity

See https://github.com/Kotlin/kotlinx.coroutines/blob/master/ui/coroutines-guide-ui.md.

Implement CoroutineScope:

class YourActivity : AppCompatActivity(), CoroutineScope {

Add a local variable job and initialize it:

private lateinit var job: Job

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    job = Job()
}

Create a coroutine context and cancel it on Activity destroy:

override fun onDestroy() {
    job.cancel()
    super.onDestroy()
}

override val coroutineContext: CoroutineContext
    get() = Dispatchers.Main + job

For Fragment (the same as in Activity)

Implement CoroutineScope:

class YourFragment : Fragment(), CoroutineScope {

Create a local variable job and initialize it in onCreate(). (I tried to write private val job: Job = Job(), but bumped into problem that in ViewPager you will create Fragments and their jobs. As we will cancel the job in onDestroy() during swiping in ViewPager, we should recreate the job).

private lateinit var job: Job

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    ...
    job = Job()
}

Create a coroutine context and cancel it on Fragment destroy:

override val coroutineContext: CoroutineContext
    get() = Dispatchers.Main + job // You can use different variants here. 

override fun onDestroy() {
    job.cancel()
    super.onDestroy()
}

A launch example

Use launch as usual:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    launch {
        // Wait for result of I/O operation without blocking the main thread.
        withContext(Dispatchers.IO) {
            interactor.getCountry().let {
                countryName = it.name
            }
        }

        // Update views in the UI thread.
        country.updateCaption(countryName)
    }
}

In my case a problem occured when I used API requests with usual callbacks. A launch interior inside a callback hasn't been called. So I rewrote that code with interactors.

CoolMind
  • 26,736
  • 15
  • 188
  • 224
7

My teammate helped me to find the solution. I had to increase the coroutines version to 1.0.0-RC1. For everyone who may don't know about the changes in using Android coroutines:

  • I had to change the UI context of coroutine to Dispatchers.Main
  • I used old experimental coroutines version (0.23 maybe) so for everyone who don't know - now launch is deprecated and you should use structured concurrency (for example coroutineScope) instead.
  • Now async function cannot be run outside the scope.

I hope I will help someone. Don't waste a time. Happy programming!

Patryk Kubiak
  • 1,679
  • 2
  • 11
  • 17
0

The implementation version must be >= the testing version

build.gradle (:mobile)

dependencies {
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines")

    // Testing
    testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutines"
    androidTestImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutines"
}

build.gradle (Project)

buildscript {
    ...
    ext.coroutines = '1.3.6'
}

FAILURE FIXED

FAILURE: Build failed with an exception.

* What went wrong:
Could not determine the dependencies of task ':app:processDebugAndroidTestManifest'.
> Could not resolve all task dependencies for configuration ':app:debugAndroidTestRuntimeClasspath'.
    > Could not resolve org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.5.
    Required by:
        project :app
     > Cannot find a version of 'org.jetbrains.kotlinx:kotlinx-coroutines-core' that satisfies the version constraints:
          Dependency path 'Open Weather:app:unspecified' --> 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.5'

GL

Community
  • 1
  • 1
Braian Coronel
  • 22,105
  • 4
  • 57
  • 62
0

Simply add "mavenCentral()" to build.gradle bellow build script: I fixed using this.

buildscript {
    ext.kotlin_version = '1.3.72'

    repositories {
        google()
        jcenter()

    }
    dependencies {
        classpath 'com.android.tools.build:gradle:4.0.0'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        mavenCentral() //Add this Line only <<<<<<<<<<<<<<<<<<
    }
}
Vishva Vijay
  • 340
  • 3
  • 11
  • Thanks for `mavenCentral()` in `allprojects repositories`! I am replacing `jcenter()` with `maven()`, because `jCenter` will close in May. – CoolMind Feb 12 '21 at 08:28