Ktor 这是一个 Kotlin 官方打造的 Web 框架,除了提供 HTTP 服务外,Ktor 还为和客户端提供了配套的库,用来进行 HTTP 请求。当然我们已经有Retrofit
等其他库完成类似功能,但是作为Kotlin亲儿子,Ktor
与Coroutine
的搭配更加天衣无缝。
接下来我们通过一个小例子学习一下Ktor在Android上的使用。
Retrofit
一样,Ktor
在HTTP通信、JSON解析等功能模块提供了多个可选项,我们选择使用okhttp
和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"
}
dependencies {
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.3"
}
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 提供的API获取天气信息
基于MVVM开发,ViewModel
封装HTTP请求,将返回的数据通过LiveData
通知到UI
基于Okhttp
创建一个HttpClient ,整个代码非常DSL
private val httpClient = HttpClient(OkHttp) {
install(JsonFeature) {
serializer = KotlinxSerializer(
Json(
JsonConfiguration.Stable.copy()
)
)
}
}
通过httpClient就可以进行http请求了。
viewModelScope.launch
开启协程,httpClient.post
进行异步请求。
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)
}
}
}
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
)
订阅ViewModel,获取数据后更新View
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
现在也支持Coroutine
的使用,但是Ktor
中使用Coroutine
的成本更低,而且Ktor支持Kotlin MPP,当有跨平台需求时Ktor绝对是一个好选择。