Help us understand the problem. What is going on with this article?

Androidで、ktor + coroutines で通信をする。

Android で、通信処理を実装しようとすると、retrofit が1番最初に思いつきます。
ただ、選択肢は多い方がいいと思いますので、マルチプラットフォームで実装出来る ktor を紹介したいと思います。

gradle

  • ktor

ktor は、マルチプラットフォーム対応なので、通信ライブラリーも選択可能です。
Androidの場合、OkHttp, Android があります。
今回は、OkHttp にします。
また、Json も同様に Gson, Jackson, Kotlinx.Serialization が選択が出来ます。
今回は、Kotlinx.Serialization にします。

dependencies {
    implementation "io.ktor:ktor-client-core:1.3.1"
    implementation "io.ktor:ktor-client-android:1.3.1"
    implementation "io.ktor:ktor-client-okhttp:1.3.1"
    implementation "io.ktor:ktor-client-serialization-jvm:1.3.1"
}
  • coroutines
dependencies {
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.3"
}
  • serialization
    dependencies {
        classpath 'com.android.tools.build:gradle:3.6.1'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
    }
apply plugin: 'kotlinx-serialization'

dependencies {
    implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:0.20.0"
}

OpenWeather から天気の情報を取得してみたいと思います。
ログインして、Keyは取得済みとします。

ViewModel

まず、ktorを初期化する。
OkHttp と KotlinxSerializer を使用します。

    private val httpClient = HttpClient(OkHttp) {
        install(JsonFeature) {
            serializer = KotlinxSerializer(
                Json(
                    JsonConfiguration.Stable.copy()
                )
            )
        }
    }

上記を使って、天気情報を取得する処理を実装します。
viewModelScope.launch が、coroutines の実装になります。
これだけで、非同期で通信する処理が実装出来ます。
また、取得できたら、LiveData を使って、UI側に通知します。

    val openWeatherMapLiveData = MutableLiveData<OpenWeatherMapJson>()

    fun getOpenWeatherMapJson() {
        viewModelScope.launch {
            try {
                val openWeatherMapJson = httpClient.post<OpenWeatherMapJson>("https://api.openweathermap.org/data/2.5/weather?q=yokohama&appid={KEY}") {
                    contentType(ContentType.Application.Json)
                }
                openWeatherMapLiveData.postValue(openWeatherMapJson)
            } catch (e:Exception) {
                Log.e("w", e.message)
            }
        }
    }
  • OpenWeatherMapJson

Json部分の実装は、省略しますが、下記のような data class を用意します。

@Serializable
data class OpenWeatherMapJson(
    val coord: Coord,
    val weather: List<Weather>,
    val base: String,
    val main: Main,
    val visibility: Int,
    val wind: Wind,
    val clouds: Clouds,
    val dt: Int,
    val sys: Sys,
    val timezone: Int,
    val id: Int,
    val name: String,
    val cod: Int
)

Activity

実際に取得する処理を実装します。
ViewModel を使って、非同期で通信し、レスポンスを受け取ったら、UIに表示する処理になります。

class MainActivity : AppCompatActivity() {

    private val viewModel by viewModels<MainViewModel>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        setSupportActionBar(toolbar)

        fab.setOnClickListener { view ->
            viewModel.getOpenWeatherMapJson()
        }
        viewModel.openWeatherMapLiveData.observe(this, Observer {
            textView.text = it.name
        })
    }
}

まとめ

retrofit でも同様なことが出来ます。
Android で、通信処理を実装する場合の選択肢として、ktor も使えますので是非使ってみてください。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away