6
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Android】Kotlin コルーチン(coroutine)で非同期処理完了を待ち合わせして非同期結果を取得する

Posted at

非同期処理で実行した結果を待ちわせしてMainスレッドで利用したいケースがあると思う。
コールバック(callback)を利用する等のいくつかの方法があるが、コルーチンの場合は簡単に実装できる。

まず最初に簡単にコルーチンで非同期で文字列を出力するだけの処理を実装してみる。(待ち合わせの処理はしない例)

CoroutineRepository.kt
class CoroutineRepository {

    // 非同期で3秒後にログを出力する
    fun execute() {
        Log.d("Coroutine", "execute start")
        var ayncString: String?
        GlobalScope.launch {
            withContext(Dispatchers.IO) {
                // 3秒スリープ(重たい処理)
                Thread.sleep(3000)
                ayncString = "123"
                Log.d("Coroutine", "ayncString:$ayncString")
            }
        }
        Log.d("Coroutine", "execute end")
    }
}

実行確認はActivityで行う。
実行確認用のActivityを用意する。

MainActivity.kt
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        Log.d("Coroutine", "onCreate")
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // ここで実行
        CoroutineRepository().execute()
    }

    override fun onStart() {
        Log.d("Coroutine", "onStart")
        super.onStart()
    }

    override fun onResume() {
        Log.d("Coroutine", "onResume")
        super.onResume()
    }
}

Activityを起動してみるとログに出力は↓のようになる。

onCreate
execute start
execute end
onStart
onResume
ayncString:123

非同期処理なので、Activityのライフサイクルは onResume まで進む。
3秒経過したら非同期処理のログが表示される。

コルーチンではなくThreadを使用しても同じように実装できる。

CoroutineRepository.kt
class CoroutineRepository {

    // Threadの例
    fun executeThread() {
        Log.d("Coroutine", "executeThread start")
        var ayncString: String?
        Thread {
            // 3秒スリープ(重たい処理)
            Thread.sleep(3000)
            ayncString = "123"
            Log.d("Coroutine", "ayncString:$ayncString")
        }.start()
        Log.d("Coroutine", "executeThread end")
    }
}

ここからが本番
非同期が完了した文字列を待ち合わせて取得したい。
runBlocking を利用すると簡単に実装可能である。

CoroutineRepository.kt
class CoroutineRepository {

    // 非同期内でセットした文字列を返す
    fun executeAwait(): String? {
        Log.d("Coroutine", "executeAwait start")
        var ayncString: String?
        runBlocking {
            withContext(Dispatchers.IO) {
                // 3秒スリープ(重たい処理)
                Thread.sleep(3000)
                ayncString = "123"
            }
        }
        return ayncString
    }
}
MainActivity.kt
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        Log.d("Coroutine", "onCreate")
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // 非同期処理を実行して文字列を出力
        val ayncString = CoroutineRepository().executeAwait()
        Log.d("Coroutine", "ayncString:$ayncString")
    }

    override fun onStart() {
        Log.d("Coroutine", "onStart")
        super.onStart()
    }

    override fun onResume() {
        Log.d("Coroutine", "onResume")
        super.onResume()
    }
}

実行してみるとログに出力は↓のようになる。

onCreate
executeAwait start
ayncString:123
onStart
onResume

待ち合わせをするので文字列を取得してからActivityのライフサイクルが進むことがわかる。(onCreateで3秒待ち合わせをすることになる)

メソッドを分割したい場合は↓のようにも実装することができる。

CoroutineRepository.kt
class CoroutineRepository {

    // 非同期内でセットした文字列を返す
    fun executeAwait(): String? {
        Log.d("Coroutine", "executeAwait start")
        var ayncString: String?
        runBlocking {
            ayncString = execute()
        }
        return ayncString
    }

    suspend fun execute(): String? {
        return withContext(Dispatchers.IO) {
            // 3秒スリープ(重たい処理)
            Thread.sleep(3000)
            "123"
        }
    }
}

コルーチンの非同期処理は簡単!

6
11
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?