面试题答案
一键面试- 利用协程实现异步网络请求
- 引入依赖:在
build.gradle.kts
中添加Ktor和协程相关依赖。例如:
- 引入依赖:在
implementation("io.ktor:ktor - client - core:2.3.3")
implementation("io.ktor:ktor - client - okhttp:2.3.3")
implementation("org.jetbrains.kotlinx:kotlinx - coroutines - android:1.7.3")
- 创建Ktor客户端:
val client = HttpClient(OkHttp) {
install(ContentNegotiation) {
json()
}
}
- 使用协程发起异步请求:在协程中使用
client
发起网络请求。例如:
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
fun main() = runBlocking {
launch {
val response = client.get<String>("https://example.com/api/data")
println(response)
}
}
- 避免阻塞主线程
- 在Android中,Kotlin协程的
Dispatchers.Main
用于主线程,而发起网络请求等耗时操作应使用Dispatchers.IO
或Dispatchers.Default
。例如:
- 在Android中,Kotlin协程的
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
fun main() = runBlocking {
launch {
val result = withContext(Dispatchers.IO) {
client.get<String>("https://example.com/api/data")
}
println(result)
}
}
- 处理异步操作中的异常情况
- 使用try - catch块:在协程中使用
try - catch
捕获异常。例如:
- 使用try - catch块:在协程中使用
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
fun main() = runBlocking {
launch {
try {
val response = client.get<String>("https://example.com/api/data")
println(response)
} catch (e: Exception) {
e.printStackTrace()
}
}
}
- 使用
coroutineScope
和supervisorScope
:coroutineScope
会等待所有子协程完成,并且如果一个子协程抛出异常,其他子协程会被取消。supervisorScope
则不同,一个子协程的异常不会影响其他子协程。例如:
import kotlinx.coroutines.*
fun main() = runBlocking {
coroutineScope {
launch {
try {
val response = client.get<String>("https://example.com/api/data")
println(response)
} catch (e: Exception) {
e.printStackTrace()
}
}
}
}
- 使用
Kotlin
的Result
类型(可自定义类似功能):可以创建一个Result
类来封装成功或失败的结果,避免在多个地方重复使用try - catch
。例如:
sealed class Result<T> {
data class Success<T>(val value: T) : Result<T>()
data class Failure<T>(val exception: Exception) : Result<T>()
}
suspend fun <T> safeApiCall(apiCall: suspend () -> T): Result<T> {
return try {
Result.Success(apiCall.invoke())
} catch (e: Exception) {
Result.Failure(e)
}
}
然后在协程中使用:
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
fun main() = runBlocking {
launch {
val result = safeApiCall { client.get<String>("https://example.com/api/data") }
when (result) {
is Result.Success -> println(result.value)
is Result.Failure -> result.exception.printStackTrace()
}
}
}