Kotlin协程调用网络请求示例
下面是一个使用Kotlin协程进行网络请求的完整示例,包括依赖配置、代码实现和异常处理。
1. 添加依赖
首先在build.gradle
(Module)中添加必要的依赖:
dependencies {
// 协程核心库
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3'
// Retrofit网络库
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
// 生命周期相关的协程作用域
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2'
}
2. 定义数据模型和API接口
// 数据模型
data class User(
val id: Int,
val name: String,
val email: String
)
// API接口定义
interface ApiService {
@GET("users/{id}")
suspend fun getUser(@Path("id") userId: Int): User
@POST("users")
suspend fun createUser(@Body user: User): User
}
3. 创建Retrofit实例
object RetrofitClient {
private const val BASE_URL = "https://api.example.com/"
val apiService: ApiService by lazy {
Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(ApiService::class.java)
}
}
4. 使用协程进行网络请求
在ViewModel中使用
class UserViewModel : ViewModel() {
private val _user = MutableStateFlow<User?>(null)
val user: StateFlow<User?> = _user
private val _error = MutableStateFlow<String?>(null)
val error: StateFlow<String?> = _error
// 获取用户信息
fun fetchUser(userId: Int) {
viewModelScope.launch {
try {
_user.value = RetrofitClient.apiService.getUser(userId)
_error.value = null
} catch (e: Exception) {
_error.value = "获取用户失败: ${e.message}"
}
}
}
// 创建用户
fun createUser(name: String, email: String) {
viewModelScope.launch {
try {
val newUser = User(0, name, email)
_user.value = RetrofitClient.apiService.createUser(newUser)
_error.value = null
} catch (e: Exception) {
_error.value = "创建用户失败: ${e.message}"
}
}
}
}
在Activity/Fragment中调用
class UserActivity : AppCompatActivity() {
private val viewModel: UserViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_user)
// 观察用户数据
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.user.collect { user ->
user?.let {
// 更新UI
textViewName.text = it.name
textViewEmail.text = it.email
}
}
}
}
// 观察错误信息
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.error.collect { error ->
error?.let {
Toast.makeText(this@UserActivity, it, Toast.LENGTH_SHORT).show()
}
}
}
}
// 触发获取用户
buttonFetch.setOnClickListener {
val userId = editTextUserId.text.toString().toIntOrNull() ?: return@setOnClickListener
viewModel.fetchUser(userId)
}
}
}
5. 不使用ViewModel的简单示例
// 在Activity/Fragment中直接使用协程
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
buttonFetch.setOnClickListener {
lifecycleScope.launch {
try {
val user = withContext(Dispatchers.IO) {
RetrofitClient.apiService.getUser(1)
}
textViewName.text = user.name
} catch (e: Exception) {
Toast.makeText(this@MainActivity, "Error: ${e.message}", Toast.LENGTH_SHORT).show()
}
}
}
}
}
关键点说明
-
suspend函数:API接口方法使用
suspend
修饰符,表示这是一个可挂起的函数 -
协程作用域:
viewModelScope
:与ViewModel生命周期绑定lifecycleScope
:与Activity/Fragment生命周期绑定
-
线程调度:
Dispatchers.IO
:用于网络请求等IO操作Dispatchers.Main
:用于更新UI(默认在Android主线程)
-
异常处理:使用try-catch捕获网络请求可能抛出的异常
-
状态管理:使用
StateFlow
或LiveData
来观察数据变化
这个示例展示了如何使用Kotlin协程进行网络请求,包括错误处理和UI更新,是Android开发中常见的网络请求模式。