单例封装retrofit+拦截器

public class RightRetroFactory {
    private static OkHttpClient httpClient = new OkHttpClient.Builder()
            .addInterceptor(new LoggingInterceptor()).connectTimeout(30, TimeUnit.SECONDS)
            .readTimeout(30, TimeUnit.SECONDS)
            .build();
    private static ApiServer retrofitService = new Retrofit.Builder()
            .baseUrl(Api.LEFT_PATH)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
            .client(httpClient)
            .build()
            .create(ApiServer.class);
    //单列模式
    public static ApiServer getInstance() {
        return retrofitService;
    }
}
<think>我们需要封装一个基于Kotlin、Flow、Retrofit和协程的网络请求框架。要求包括: 1. 统一处理异常(如网络错误、服务器返回的错误等) 2. 统一处理登录(如遇到未登录的情况,统一跳转到登录页面) 3. 封装返回实体基类,用于处理统一的数据结构(通常包含code、message、data等字段) 4. 提供使用实 步骤: 1. 定义数据返回的基类(BaseResponse) 2. 封装网络请求的异常类(如ServerException等) 3. 封装Retrofit创建过程() 4. 使用协程和Flow来封装网络请求,并处理异常和登录状态 5. 在Repository层调用封装好的网络请求 6. 在ViewModel中收集Flow并处理UI状态 注意:统一处理登录,我们可以在基类中检查返回的code,比如当code为401(未授权)时,触发登录逻辑(如跳转到登录页面)。 实现: 第一步:定义数据基类 假设服务器返回的数据格式为: { "code": 0, // 0表示成功,非0表示错误 "message": "成功", "data": {} // 实际数据 } 第二步:定义异常类 第三步:封装网络请求,使用Flow进行结果分发,并处理异常和登录状态 第四步:创建Retrofit 我们开始编写代码:</think>下面是一个基于 Kotlin + Flow + Retrofit + 协程的完整网络请求框架封装方案,包含统一异常处理、登录状态管理和使用示: --- ### 1. 网络请求基类封装 #### 1.1 响应基类 ```kotlin // 服务器响应基类 data class BaseResponse<T>( val code: Int, val message: String? = null, val data: T? = null ) { fun isSuccess() = code == 200 fun isUnauthorized() = code == 401 } ``` #### 1.2 异常处理类 ```kotlin // 网络请求异常封装 sealed class NetworkException( val errorCode: Int, val errorMsg: String? ) : Exception(errorMsg) { // 服务器返回的业务异常 class ApiException(code: Int, msg: String?) : NetworkException(code, msg) // 网络异常 class NetworkError(throwable: Throwable) : NetworkException(-1, throwable.message ?: "网络连接失败") // 数据解析异常 class ParseError(throwable: Throwable) : NetworkException(-2, "数据解析失败: ${throwable.message}") // 未登录异常 object Unauthorized : NetworkException(401, "请重新登录") } ``` --- ### 2. Retrofit & Flow 封装 #### 2.1 Retrofit 构建器 ```kotlin object RetrofitBuilder { private const val BASE_URL = "https://your.api.com/" private val okHttpClient = OkHttpClient.Builder() .addInterceptor(LoggingInterceptor()) // 日志拦截器 .addInterceptor(AuthInterceptor()) // 认证拦截器 .build() private val retrofit = Retrofit.Builder() .baseUrl(BASE_URL) .client(okHttpClient) .addConverterFactory(GsonConverterFactory.create()) .build() fun <T> createService(serviceClass: Class<T>): T = retrofit.create(serviceClass) } // 认证拦截器(自动添加Token) class AuthInterceptor : Interceptor { override fun intercept(chain: Interceptor.Chain): Response { val request = chain.request().newBuilder() .addHeader("Authorization", "Bearer ${UserSession.token}") .build() return chain.proceed(request) } } ``` #### 2.2 Flow 网络请求封装 ```kotlin // 网络请求执行器 object NetworkRequest { suspend fun <T> safeApiCall( apiCall: suspend () -> BaseResponse<T> ): Flow<Result<T>> = flow { try { val response = apiCall() when { response.isSuccess() -> { response.data?.let { emit(Result.success(it)) } ?: throw NetworkException.ParseError(NullPointerException("数据为空")) } response.isUnauthorized() -> throw NetworkException.Unauthorized else -> throw NetworkException.ApiException(response.code, response.message) } } catch (e: Exception) { emit(Result.failure(handleException(e))) } } private fun handleException(e: Exception): NetworkException = when (e) { is NetworkException -> e is IOException -> NetworkException.NetworkError(e) is JsonSyntaxException -> NetworkException.ParseError(e) else -> NetworkException.ApiException(-999, "未知错误: ${e.message}") } } // 登录状态管理 object UserSession { var token: String? = null fun clearSession() { token = null // 跳转到登录页面(通过Event或LiveData通知) EventBus.post(LoginExpiredEvent()) } } ``` --- ### 3. 使用示 #### 3.1 API 接口定义 ```kotlin interface UserService { @GET("user/profile") suspend fun getUserProfile(): BaseResponse<UserProfile> @POST("auth/login") suspend fun login(@Body request: LoginRequest): BaseResponse<LoginResponse> } // 数据模型 data class UserProfile(val name: String, val email: String) data class LoginRequest(val username: String, val password: String) data class LoginResponse(val token: String) ``` #### 3.2 Repository 层 ```kotlin class UserRepository { private val userService = RetrofitBuilder.createService(UserService::class.java) fun getUserProfile(): Flow<Result<UserProfile>> = NetworkRequest.safeApiCall { userService.getUserProfile() } fun login(username: String, password: String): Flow<Result<LoginResponse>> = NetworkRequest.safeApiCall { userService.login(LoginRequest(username, password)) } } ``` #### 3.3 ViewModel 层 ```kotlin class UserViewModel : ViewModel() { private val repo = UserRepository() private val _userProfile = MutableStateFlow<Result<UserProfile>?>(null) val userProfile: StateFlow<Result<UserProfile>?> = _userProfile fun loadUserProfile() { viewModelScope.launch { repo.getUserProfile().collect { result -> _userProfile.value = result result.onFailure { handleError(it) } } } } private fun handleError(throwable: Throwable) { if (throwable is NetworkException.Unauthorized) { UserSession.clearSession() // 触发登录跳转 } // 其他错误处理(如Toast提示) } } ``` #### 3.4 UI 层使用 ```kotlin // Activity/Fragment viewModel.userProfile.onEach { result -> when { result?.isSuccess() -> showProfile(result.getOrNull()) result?.isFailure() -> showError(result.exceptionOrNull()) } }.launchIn(lifecycleScope) ``` --- ### 关键设计解析: 1. **统一响应处理**: - 通过 `BaseResponse` 标准化服务器响应格式 - `safeApiCall` 自动处理成功/失败状态转换 2. **异常处理机制**: - 使用密封类 `NetworkException` 封装所有错误类型 - 在 `handleException` 中统一转换异常类型 3. **登录状态管理**: - `AuthInterceptor` 自动添加 Token - 遇到 401 时通过 `UserSession.clearSession()` 触发登录跳转 - 使用 EventBus 或 LiveData 通知 UI 层跳转 4. **Flow 优势**: - 天然支持协程生命周期 - 自动处理背压 - 通过 `StateFlow` 实现状态持久化 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值