Retrofit + 协程封装实战:高效处理Android网络请求与状态管理

Android开发中,网络请求是必不可少的功能,而Retrofit和Kotlin协程的结合为网络请求提供了简洁高效的解决方案。本文通过实战演示,详细讲解如何封装Retrofit + 协程,实现统一的网络请求错误处理加载状态管理。从依赖配置、数据模型定义、API接口设计,到ViewModel中的数据管理和UI层的状态观察,一步步带你掌握现代Android开发中的网络请求最佳实践。无论是初学者还是经验丰富的开发者,都能从中受益,提升开发效率和代码质量。

以下是一个完整的 Retrofit + 协程 封装实战示例,包括网络请求的封装、错误处理、加载状态管理等。

1. 添加依赖
build.gradle 中添加必要的依赖:

dependencies {
    // Retrofit
    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
    implementation 'com.squareup.okhttp3:logging-interceptor:4.9.3'

    // Kotlin Coroutines
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4'
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4'

    // Lifecycle (用于协程的 lifecycleScope)
    implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1'
}

2. 定义数据模型

data class User(
    val id: Int,
    val name: String,
    val email: String
)

3. 定义 API 接口
使用 Retrofit 的注解定义 API 接口:

interface ApiService {
    @GET("users/{id}")
    suspend fun getUser(@Path("id") id: Int): User

    @GET("users")
    suspend fun getUsers(): List<User>
}

4. 封装 Retrofit 客户端
创建一个单例的 Retrofit 客户端:

object RetrofitClient {
    private const val BASE_URL = "https://jsonplaceholder.typicode.com/"

    private val okHttpClient = OkHttpClient.Builder()
        .addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
        .build()

    private val retrofit = Retrofit.Builder()
        .baseUrl(BASE_URL)
        .client(okHttpClient)
        .addConverterFactory(GsonConverterFactory.create())
        .build()

    val apiService: ApiService by lazy {
        retrofit.create(ApiService::class.java)
    }
}

5. 封装网络请求
封装一个通用的网络请求工具类,处理协程的异常加载状态

sealed class Result<out T> {
    data class Success<out T>(val data: T) : Result<T>()
    data class Error(val exception: Throwable) : Result<Nothing>()
    object Loading : Result<Nothing>()
}

object NetworkHelper {
    suspend fun <T> safeApiCall(apiCall: suspend () -> T): Result<T> {
        return try {
            Result.Success(apiCall())
        } catch (e: Exception) {
            Result.Error(e)
        }
    }
}

6. 在 ViewModel 中使用
ViewModel 中发起网络请求,并管理 UI 状态:

class UserViewModel : ViewModel() {
    private val _userState = MutableLiveData<Result<User>>()
    val userState: LiveData<Result<User>> get() = _userState

    private val _usersState = MutableLiveData<Result<List<User>>>()
    val usersState: LiveData<Result<List<User>>> get() = _usersState

    fun fetchUser(userId: Int) {
        viewModelScope.launch {
            _userState.value = Result.Loading
            _userState.value = NetworkHelper.safeApiCall {
                RetrofitClient.apiService.getUser(userId)
            }
        }
    }

    fun fetchUsers() {
        viewModelScope.launch {
            _usersState.value = Result.Loading
            _usersState.value = NetworkHelper.safeApiCall {
                RetrofitClient.apiService.getUsers()
            }
        }
    }
}
  1. Activity/Fragment 中观察数据
    UI 层观察 ViewModel 的数据,并更新 UI:
class UserActivity : AppCompatActivity() {
    private val viewModel: UserViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_user)

        // 观察用户数据
        viewModel.userState.observe(this) { result ->
            when (result) {
                is Result.Loading -> showLoading()
                is Result.Success -> showUser(result.data)
                is Result.Error -> showError(result.exception.message)
            }
        }

        // 观察用户列表数据
        viewModel.usersState.observe(this) { result ->
            when (result) {
                is Result.Loading -> showLoading()
                is Result.Success -> showUsers(result.data)
                is Result.Error -> showError(result.exception.message)
            }
        }

        // 发起请求
        viewModel.fetchUser(1)
        viewModel.fetchUsers()
    }

    private fun showLoading() {
        // 显示加载动画
    }

    private fun showUser(user: User) {
        // 更新 UI 显示用户信息
    }

    private fun showUsers(users: List<User>) {
        // 更新 UI 显示用户列表
    }

    private fun showError(message: String?) {
        // 显示错误信息
    }
}

8. 错误处理
NetworkHelper 中已经捕获了异常,可以根据不同的异常类型(如网络异常、解析异常等)进行更细致的处理:

catch (e: IOException) {
    Result.Error(Exception("网络连接失败,请检查网络设置"))
} catch (e: HttpException) {
    Result.Error(Exception("服务器错误: ${e.code()}"))
} catch (e: Exception) {
    Result.Error(Exception("未知错误: ${e.message}"))
}

9. 总结
通过以上封装,我们实现了以下功能:

Retrofit + 协程 的网络请求封装

  1. 统一的错误处理和加载状态管理。

  2. ViewModel 中管理数据,确保 UI 与数据分离。

  3. 在 UI 层观察数据变化,并更新 UI。

  4. 这种封装方式不仅提高了代码的可读性和可维护性,还能有效减少重复代码,适合中大型项目的开发。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值