kotlinコルーチンによる非同期処理を実装する

kotlinのコルーチンを使って、Webアクセスを含めた非同期処理を実装してみます。

下準備としてGradleにライブラリを追加します。

 // For Coroutine
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4"

ViewModelの中に非同期処理を書いていきます。

    //コルーチンスコープ内で呼び出す
    @UiThread
    private fun getURLInfo(){
        viewModelScope.launch {
            val result = connect()
            decodeJson(result)
        }
    }

connectはワーカースレッドでWebアクセス処理を行い、decodeJSONはUIスレッドでString文字列の解析を行います。

別々のスレッドで行う処理を1つの非同期処理ブロックとして記載します。

connectは以下のようにsuspendをつけることで、非同期処理なんだけど、connectの処理が終わってデータをダウンロードした後に、decodeJsonを行うことができます。

   //URLに接続する。suspendを使うことで他の処理を中断させることができる。
    @WorkerThread
    private suspend fun connect():String{
        //ワーカースレッドとしてスレッド分離する
        val returnVal = withContext(Dispatchers.IO){
            var result = ""
            val url = URL(url)
            val con = url.openConnection() as? HttpURLConnection
            con?.let {
                try {
                    it.connect()
                    val stream = it.inputStream
                    result = iStreamToString(stream)
                    println(result)
                    stream.close()
                }catch (err:SocketTimeoutException){
                    println(err)
                }
                it.disconnect()
            }
            result
        }
        return returnVal
    }

接続した結果はInputStreamで得られるので、Stringに変換する関数を以下の通り作ります。

また、JSONをデコードする関数をUIスレッドで宣言します。(Json解析の中身は別の記事で書こうと思いますが、ここでUIの更新を行い、文字列の表示などをします。)

    //InputStreamをStringに変換する
    private fun iStreamToString(stream:InputStream):String{
        val sb = StringBuilder()
        val reader = BufferedReader(InputStreamReader(stream,"UTF-8"))
        var line = reader.readLine()

        while (line != null){
            sb.append(line)
            line = reader.readLine()
        }
        reader.close()
        return sb.toString()
    }

    @UiThread
    private fun decodeJson(result:String){
        //JSONの解析をする
    }

ABOUTこの記事をかいた人

個人アプリ開発者。Python、Swift、Unityのことを発信します。月間2.5万PVブログ運営。 Twitter:@yamagablog