AsyncTask を Kotlin のコルーチンに置き換える方法

Android アプリでまだ AsyncTask を使用していますか? おそらくもうそうすべきではありません。 これらを Kotlin のコルーチンに置き換える方法は次のとおりです。

Android では長い間、アプリの作成時に非同期で何かを行う必要がある場合、おそらく AsyncTask を使用していました。 AsyncTask は、バックグラウンドで操作を実行し、終了時に値を返すことを簡単に (おそらく) 可能にする Android フレームワークの API です。 それは理にかなっています。 Kotlin のコルーチンとは異なり、AsyncTask はしばらく前から存在しており、すぐに組み込まれています。

ただし、AsyncTask の設計哲学と実装はどちらも、長年にわたってやや時代遅れになってきました。 そのため、Google は、 AsyncTask API が非推奨になりました. 必要に応じて引き続き使用できますが、Google はそうすることをお勧めしません。 幸いなことに、Kotlin 言語の機能であるコルーチンなど、AsyncTask の代替手段がたくさんあります。

Kotlin のコルーチン API は、さまざまなことを実行できる非常に強力なフレームワークです。 この記事は、可能なことのほんの表面をなぞるだけです。 AsyncTask からコルーチンに移行するために必要な基本について説明します。

コルーチンのサポートの追加

コルーチンの使用を開始する前に、コルーチンを実際にプロジェクトに追加する必要があります。

Kotlin サポートの追加

すでに Kotlin を実装している場合は、次のセクションに進んでください。 それ以外の場合は、プロジェクトに Kotlin サポートを追加する必要があります。 詳細については、既存のプロジェクトへの Kotlin の追加に関する私のチュートリアルをご覧ください。

コルーチン ライブラリの追加

モジュールレベルで build.gradleには、次の依存関係が含まれます。

dependencies {
...
implementation 'org.jetbrains.kotlinx: kotlinx-coroutines-core: 1.5.0'
implementation 'org.jetbrains.kotlinx: kotlinx-coroutines-android: 1.5.0'
}

プロジェクトを同期すると、Kotlin のコルーチンが使用できるようになります。

コルーチンの使用

CoroutineScope の実装

コルーチンを使用するには、CoroutineScope インスタンスを使用できる必要があります。 これを行う簡単な方法は、それを含むクラスに実装するだけです。

たとえば、CoroutineScope をアクティビティに実装するには、次のようにします。

classSomeActivity : AppCompatActivity, CoroutineScope by MainScope() {
...

override fun onDestroy(){
super.onDestroy()

cancel()
}
}

これにより、SomeActivity は MainScope クラスを介して CoroutineScope インターフェイスを実装します。 MainScope は、CoroutineScope のメソッドを使用できるようにしながら、CoroutineScope のすべての実装ロジックを処理します。 電話をかける cancel()onDestroy() アクティビティの終了後に非同期ロジックが実行を継続しないようにします。

AsyncTask をコルーチンに置き換える

バックグラウンドで長時間実行される操作を実行し、最終的に文字列を返す AsyncTask がアクティビティ内にあるとします。 以下のようなものです。

private inner classSomeTask : AsyncTask() {
override fun doInBackground(vararg params: Void): String {
try {
//Pretend this is an actual operation that takes 10 seconds and not just sleeping.
Thread.sleep(10000);
} catch (e: InterruptedException) {}

return"SomeString";
}

override fun onPostExecute(result: String) {
val someTextView = findViewById(R.id.some_text_view)
someTextView.text = result
}
}

これをコルーチンに置き換えるのは簡単です。 ただ使用してください async() 方法。 コトリンの async() 起動されたスレッド上で実行されますが、非同期で実行されます。 これは、適切なスレッドの使用を心配することなくビューなどを更新できることを意味します。

classSomeActivity : AppCompatActivity(), CoroutineScope by MainScope() {
...

private fun doOperation(){
async {
//Inside coroutine scopes (like inside async here), delay is used instead of Thread.sleep.
delay(10000)

val someTextView = findViewById(R.id.some_text_view)
someTextView.text = "SomeString"
}
}
}

ご覧のとおり、コルーチンの使用は、AsyncTask を使用するよりもはるかに簡単です。 ただ電話する必要はない async() ただし、それをそのままにしましょう。 それへの参照を保持し、完了するまで待つこともできます。

val asyncJob = async {
//Some operation
}
//Pause here until the async block is finished.
asyncJob.await()

//This won't run until asyncJob finishes, but other operations started before the job, or started from another method, can still run.
doSomethingElse()

非同期で値を返す

から値を返すこともできます async() あなたが望むなら。 したがって、元の例は次のようになります。

classSomeActivity : AppCompatActivity(), CoroutineScope by MainScope() {
...
private fun doOperation(){
val asyncJob = async {
//Inside coroutine scopes (like inside async here), delay is used instead of Thread.sleep.
delay(10000)

//Whatever the type is of the last line is what async() eventually returns.
"SomeString"
}

val result = asyncJob.await()

val someTextView = findViewById(R.id.some_text_view)
someTextView.text = result
}
}

withContext の使用

便宜上、Kotlin は以下を提供します withContext(). これは全体をインライン化します await() 値を返すだけです。

classSomeActivity : AppCompatActivity(), CoroutineScope by MainScope() {
...
private fun doOperation(){
//Run asynchronously on the main Thread.
val result = withContext(Dispatchers.Main) {
delay(10000)

"SomeResult"
}

val someTextView = findViewById(R.id.some_text_view)
someTextView.text = result
}
}

結論

上記の例は、開始するための Kotlin のコルーチンの基本的な使用法の一部にすぎません。 コルーチンをアクティビティや、適切なライフサイクルを持つものに限定する必要はありません。 基本的にどこでも実行できます。 非同期ロジックを実行するスレッドの選択など、より高度な操作もあります。 このガイドは主に、単純な AsyncTask を単純なコルーチンに置き換える方法を示すことを目的としています。

コルーチンの仕組みと、コルーチンのより高度な機能を利用する方法の詳細については、 Kotlin の公式ドキュメント.