web-dev-qa-db-ja.com

Android Kotlin 1.3でKotlinコルーチンに移行します

Kotlin 1.3のAndroidプロジェクトで安定したコルーチン関数を使用するには、build.gradleファイルで何を変更するか、クラスでインポートする必要がありますか?

build.gradleのコルーチンに関するフラグメント

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

もちろん、Android St​​udio 3.3 Previewを使用します

10
Patryk Kubiak

_build.gradle_でライブラリを

_implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-Android:1.1.1'_。

追加された場合は削除します。

_kotlin {
    experimental {
        coroutines "enable"
    }
}
_

コードでlaunchGlobalScope.launch(Dispatchers.IO)またはGlobalScope.launch(Dispatchers.Main)に変更します。

[〜#〜] update [〜#〜]

グローバルスコープの代わりにローカルコルーチンコンテキストを使用してください(たとえば、 http://kotlinlang.org/docs/reference/coroutines/coroutine-context-and-dispatchers.html を参照)。

アクティビティ用

https://github.com/Kotlin/kotlinx.coroutines/blob/master/ui/coroutines-guide-ui.md を参照してください。

CoroutineScopeを実装します:

_class YourActivity : AppCompatActivity(), CoroutineScope {
_

ローカル変数jobを追加して初期化します:

_private lateinit var job: Job

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

    job = Job()
}
_

コルーチンコンテキストを作成し、Activity destroyでキャンセルします。

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

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

フラグメントの場合Activityと同じ)

CoroutineScopeを実装します。

_class YourFragment : Fragment(), CoroutineScope {
_

ローカル変数jobを作成し、onCreate()で初期化します。 (私はprivate val job: Job = Job()を書き込もうとしましたが、ViewPagerFragmentsとそのジョブを作成するという問題にぶつかりました。onDestroy()ViewPagerのスワイプ中に、ジョブを再作成する必要があります)。

_private lateinit var job: Job

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

    ...
    job = Job()
}
_

コルーチンコンテキストを作成し、Fragment destroyでキャンセルします。

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

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

起動例

通常どおりlaunchを使用します。

_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)
    }
}
_

私の場合、通常のコールバックでAPIリクエストを使用すると問題が発生しました。コールバック内のlaunchインテリアは呼び出されていません。そこで、そのコードをインタラクターで書き直しました。

24
CoolMind

チームメイトが解決策を見つけるのを助けてくれました。コルーチンのバージョンを1.0.0-RC1に増やす必要がありました。 Androidコルーチンを使用することの変更について知らないかもしれないすべての人のために:

  • コルーチンのUIコンテキストをDispatchers.Mainに変更する必要がありました
  • 古い実験コルーチンバージョン(0.23かもしれません)を使用したので、知らないすべての人のために-現在、起動は非推奨であり、代わりに構造化同時実行(たとえばcoroutineScope)を使用する必要があります。
  • 非同期関数は、スコープ外で実行できなくなりました。

私は誰かを助けることを願っています。時間を無駄にしないでください。幸せなプログラミング!

5
Patryk Kubiak