当前位置: 首页 > news >正文

网络框架二次封装:基于Kotlin的高扩展性网络请求框架完整实现

完整目录结构

1. 架构设计1.1 分层架构1.2 核心组件1.3 接口关系图2. 基础配置实现2.1 NetworkConfig完整代码2.2 CacheConfig完整代码3. 核心网络客户端3.1 SmartHttpClient完整实现3.2 单例管理3.3 服务创建与执行4. DSL请求构建器4.1 NetworkRequest完整实现4.2 生命周期绑定4.3 线程调度控制5. 协程扩展模块5.1 Call扩展完整实现5.2 Observable扩展完整实现6. 核心组件实现6.1 CacheInterceptor完整代码6.2 RetryInterceptor完整代码6.3 ResponseProcessor完整代码7. 使用示例7.1 初始化配置7.2 API定义7.3 各种调用方式

1. 架构设计

1.1 分层架构图

[应用层]├── ViewModels├── Activities/Fragments└── Repositories│▼
[网络门面层]├── NetworkClient (全局入口)├── NetworkRequest (DSL构建器)└── CoroutineExtensions (协程支持)│▼
[核心框架层]├── SmartHttpClient (核心实现)├── Interceptors (拦截器链)└── ResponseProcessor (响应处理)│▼
[引擎层]├── Retrofit└── OkHttp

1.2 核心组件关系

NetworkClient
+getService()
SmartHttpClient
-okHttpClient: OkHttpClient
-retrofit: Retrofit
+createService()
+execute()
NetworkRequest
+call()
+onSuccess()
+onFailure()
ResponseProcessor
-statusHandlers: Map
+process()
+registerHandler()
CacheInterceptor
RetryInterceptor

2. 基础配置完整实现

2.1 NetworkConfig完整代码

/*** 网络框架全局配置*/
data class NetworkConfig(val baseUrl: String,val connectTimeout: Long = 30,val readTimeout: Long = 30,val writeTimeout: Long = 30,val interceptors: List<Interceptor> = emptyList(),val converterFactories: List<Converter.Factory> = emptyList(),val cacheConfig: CacheConfig? = null,val retryOnFailure: Boolean = true,val maxRetryCount: Int = 3,val enableLogging: Boolean = false
) {/*** 缓存配置*/data class CacheConfig(val cacheDir: File,val maxSize: Long = 10 * 1024 * 1024, // 10MBval onlineCacheTime: Int = 60, // 1分钟val offlineCacheTime: Int = 7 * 24 * 60 * 60 // 1周)class Builder {private var baseUrl: String = ""private var connectTimeout: Long = 30private var readTimeout: Long = 30private var writeTimeout: Long = 30private val interceptors = mutableListOf<Interceptor>()private val converterFactories = mutableListOf<Converter.Factory>()private var cacheConfig: CacheConfig? = nullprivate var retryOnFailure: Boolean = trueprivate var maxRetryCount: Int = 3private var enableLogging: Boolean = falsefun baseUrl(url: String) = apply { this.baseUrl = url }fun timeouts(connect: Long, read: Long, write: Long) = apply {this.connectTimeout = connectthis.readTimeout = readthis.writeTimeout = write}fun addInterceptor(interceptor: Interceptor) = apply { this.interceptors.add(interceptor) }fun addConverterFactory(factory: Converter.Factory) = apply {this.converterFactories.add(factory)}fun cacheConfig(config: CacheConfig) = apply { this.cacheConfig = config }fun retryPolicy(retryOnFailure: Boolean, maxRetryCount: Int) = apply {this.retryOnFailure = retryOnFailurethis.maxRetryCount = maxRetryCount}fun enableLogging(enable: Boolean) = apply {this.enableLogging = enable}fun build(): NetworkConfig {if (enableLogging) {interceptors.add(LoggingInterceptor())}return NetworkConfig(baseUrl = baseUrl,connectTimeout = connectTimeout,readTimeout = readTimeout,writeTimeout = writeTimeout,interceptors = interceptors,converterFactories = converterFactories,cacheConfig = cacheConfig,retryOnFailure = retryOnFailure,maxRetryCount = maxRetryCount,enableLogging = enableLogging)}}
}

2.2 CacheConfig完整代码

/*** 缓存配置独立实现*/
class CacheConfig private constructor(val cacheDir: File,val maxSize: Long,val onlineCacheTime: Int,val offlineCacheTime: Int
) {companion object {fun create(context: Context,maxSize: Long = 10 * 1024 * 1024,onlineCacheTime: Int = 60,offlineCacheTime: Int = 7 * 24 * 60 * 60): CacheConfig {val cacheDir = File(context.cacheDir, "http_cache")if (!cacheDir.exists()) {cacheDir.mkdirs()}return CacheConfig(cacheDir = cacheDir,maxSize = maxSize,onlineCacheTime = onlineCacheTime,offlineCacheTime = offlineCacheTime)}}
}

3. 核心网络客户端完整实现

3.1 SmartHttpClient完整代码

/*** 智能网络请求客户端核心实现*/
class SmartHttpClient private constructor(private val context: Context,private val config: NetworkConfig
) {private val okHttpClient: OkHttpClient by lazy {OkHttpClient.Builder().apply {connectTimeout(config.connectTimeout, TimeUnit.SECONDS)readTimeout(config.readTimeout, TimeUnit.SECONDS)writeTimeout(config.writeTimeout, TimeUnit.SECONDS)retryOnConnectionFailure(config.retryOnFailure)// 添加拦截器config.interceptors.forEach { addInterceptor(it) }// 配置缓存config.cacheConfig?.let { cacheConfig ->cache(Cache(cacheConfig.cacheDir, cacheConfig.maxSize))addInterceptor(CacheInterceptor(context, cacheConfig))}// 添加重试拦截器addInterceptor(RetryInterceptor(config.maxRetryCount))// 添加公共参数拦截器addInterceptor(CommonParamsInterceptor())}.build()}private val retrofit: Retrofit by lazy {Retrofit.Builder().apply {baseUrl(config.baseUrl)client(okHttpClient)// 添加转换器if (config.converterFactories.isEmpty()) {addConverterFactory(GsonConverterFactory.create())} else {config.converterFactories.forEach { addConverterFactory(it) }}// 默认添加RxJava支持addCallAdapterFactory(RxJava2CallAdapterFactory.create())}.build()}private val serviceCache = ConcurrentHashMap<Class<*>, Any>()private val responseProcessor = ResponseProcessor()companion object {@Volatileprivate var INSTANCE: SmartHttpClient? = nullfun initialize(context: Context, config: NetworkConfig) {INSTANCE = SmartHttpClient(context.applicationContext, config)}fun getInstance(): SmartHttpClient {return INSTANCE ?: throw IllegalStateException("SmartHttpClient must be initialized!")}}@Suppress("UNCHECKED_CAST")fun <T> createService(serviceClass: Class<T>): T {return serviceCache.getOrPut(serviceClass) {retrofit.create(serviceClass).also { service ->// 初始化服务时注册默认状态处理器if (serviceClass.isAnnotationPresent(NeedStatusHandler::class.java)) {responseProcessor.registerHandler(200, DefaultStatusHandler())}}} as T}inline fun <reified T> createService(): T = createService(T::class.java)fun <T> execute(call: Call<T>, callback: NetworkCallback<T>) {call.enqueue(object : Callback<T> {override fun onResponse(call: Call<T>, response: Response<T>) {responseProcessor.process(response, callback)}override fun onFailure(call: Call<T>, t: Throwable) {callback.onFailure(translateException(t))}})}fun <T> execute(observable: Observable<T>, callback: NetworkCallback<T>): Disposable {return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe({ response -> callback.onSuccess(response) },{ throwable -> callback.onFailure(translateException(throwable)) })}private fun translateException(t: Throwable): NetworkException {return when (t) {is SocketTimeoutException -> NetworkException(NetworkException.TIMEOUT_ERROR, "连接超时", t)is ConnectException -> NetworkException(NetworkException.CONNECT_ERROR, "连接服务器失败", t)is SSLHandshakeException -> NetworkException(NetworkException.SSL_ERROR, "证书验证失败", t)is HttpException -> NetworkException(NetworkException.HTTP_ERROR, "HTTP错误: ${t.code()}", t)is JsonParseException -> NetworkException(NetworkException.PARSE_ERROR, "数据解析错误", t)else -> NetworkException(NetworkException.UNKNOWN_ERROR, "未知网络错误", t)}}@Target(AnnotationTarget.CLASS)@Retention(AnnotationRetention.RUNTIME)annotation class NeedStatusHandlerinterface NetworkCallback<T> {fun onSuccess(response: T)fun onFailure(exception: NetworkException)}
}

4. DSL请求构建器完整实现

4.1 NetworkRequest完整代码

/*** 声明式网络请求构建器*/
class NetworkRequest<T> private constructor(private val call: Call<T>? = null,private val observable: Observable<T>? = null,private val lifecycleOwner: LifecycleOwner? = null
) {private var successCallback: (T) -> Unit = {}private var failureCallback: (NetworkException) -> Unit = {}private var completeCallback: () -> Unit = {}private var subscribeOn: Scheduler = Schedulers.io()private var observeOn: Scheduler = AndroidSchedulers.mainThread()private var retryCount: Int = 0private var retryDelay: Long = 1000private var showLoading: Boolean = falseprivate var loadingMessage: String = "加载中..."companion object {fun <T> with(lifecycleOwner: LifecycleOwner? = null): NetworkRequest<T> {return NetworkRequest(lifecycleOwner = lifecycleOwner)}}fun call(call: Call<T>): NetworkRequest<T> {this.call = callreturn this}fun observable(observable: Observable<T>): NetworkRequest<T> {this.observable = observablereturn this}fun onSuccess(block: (T) -> Unit): NetworkRequest<T> {this.successCallback = blockreturn this}fun onFailure(block: (NetworkException) -> Unit): NetworkRequest<T> {this.failureCallback = blockreturn this}fun onComplete(block: () -> Unit): NetworkRequest<T> {this.completeCallback = blockreturn this}fun subscribeOn(scheduler: Scheduler): NetworkRequest<T> {this.subscribeOn = schedulerreturn this}fun observeOn(scheduler: Scheduler): NetworkRequest<T> {this.observeOn = schedulerreturn this}fun retry(count: Int, delayMillis: Long = 1000): NetworkRequest<T> {this.retryCount = countthis.retryDelay = delayMillisreturn this}fun showLoading(show: Boolean, message: String = "加载中..."): NetworkRequest<T> {this.showLoading = showthis.loadingMessage = messagereturn this}fun execute(): Disposable? {val client = SmartHttpClient.getInstance()if (showLoading) {LoadingDialog.show(lifecycleOwner as? FragmentActivity, loadingMessage)}return when {call != null -> {client.execute(call, object : SmartHttpClient.NetworkCallback<T> {override fun onSuccess(response: T) {dismissLoading()successCallback(response)completeCallback()}override fun onFailure(exception: NetworkException) {dismissLoading()failureCallback(exception)completeCallback()}})null}observable != null -> {observable.subscribeOn(subscribeOn).observeOn(observeOn).retryWhen { errors ->errors.zipWith(Observable.range(1, retryCount + 1)) { _, i ->if (i <= retryCount) {Observable.timer(retryDelay, TimeUnit.MILLISECONDS)} else {throw Exception("Retry limit exceeded")}}.flatMap { it }}.doFinally { dismissLoading() }.subscribe({ successCallback(it) },{ val networkException = if (it is NetworkException) {it} else {client.translateException(it)}failureCallback(networkException)completeCallback() },{ completeCallback() }).also { disposable ->lifecycleOwner?.lifecycle?.addObserver(object : LifecycleEventObserver {override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {if (event == Lifecycle.Event.ON_DESTROY) {disposable.dispose()source.lifecycle.removeObserver(this)dismissLoading()}}})}}else -> throw IllegalArgumentException("Must specify either call or observable")}}private fun dismissLoading() {if (showLoading) {LoadingDialog.dismiss()}}
}

4.2 LoadingDialog实现

/*** 全局加载对话框*/
object LoadingDialog {private var dialog: AlertDialog? = nullfun show(activity: FragmentActivity?, message: String = "加载中...") {dismiss()activity ?: returndialog = AlertDialog.Builder(activity).setMessage(message).setCancelable(false).create().apply {window?.setBackgroundDrawableResource(android.R.color.transparent)show()}}fun dismiss() {dialog?.dismiss()dialog = null}
}

5. 协程扩展模块完整实现

5.1 Call扩展完整实现

/*** Call协程扩展*/
suspend fun <T> Call<T>.await(showLoading: Boolean = false,loadingMessage: String = "加载中..."
): T {val activity = getCurrentActivity()?.takeIf { showLoading }return suspendCoroutine { continuation ->activity?.runOnUiThread {LoadingDialog.show(activity as? FragmentActivity, loadingMessage)}val callback = object : SmartHttpClient.NetworkCallback<T> {override fun onSuccess(response: T) {activity?.runOnUiThread { LoadingDialog.dismiss() }continuation.resume(response)}override fun onFailure(exception: NetworkException) {activity?.runOnUiThread { LoadingDialog.dismiss() }continuation.resumeWithException(exception)}}SmartHttpClient.getInstance().execute(this, callback)}
}private fun getCurrentActivity(): Activity? {return try {val activityThread = Class.forName("android.app.ActivityThread")val currentActivityThread = activityThread.getMethod("currentActivityThread").invoke(null)val activitiesField = activityThread.getDeclaredField("mActivities")activitiesField.isAccessible = trueval activities = activitiesField.get(currentActivityThread) as Map<*, *>for (activityRecord in activities.values) {val activityRecordClass = activityRecord?.javaClassval pausedField = activityRecordClass?.getDeclaredField("paused")pausedField?.isAccessible = trueif (pausedField?.getBoolean(activityRecord) == false) {val activityField = activityRecordClass.getDeclaredField("activity")activityField.isAccessible = truereturn activityField.get(activityRecord) as Activity}}null} catch (e: Exception) {null}
}

5.2 Observable扩展完整实现

/*** Observable协程扩展*/
suspend fun <T> Observable<T>.await(retryCount: Int = 0,retryDelay: Long = 1000,showLoading: Boolean = false,loadingMessage: String = "加载中..."
): T {val activity = getCurrentActivity()?.takeIf { showLoading }return suspendCoroutine { continuation ->activity?.runOnUiThread {LoadingDialog.show(activity as? FragmentActivity, loadingMessage)}var disposable: Disposable? = nulldisposable = this.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).retryWhen { errors ->errors.zipWith(Observable.range(1, retryCount + 1)) { _, i ->if (i <= retryCount) {Observable.timer(retryDelay, TimeUnit.MILLISECONDS)} else {throw Exception("Retry limit exceeded")}}.flatMap { it }}.doFinally {activity?.runOnUiThread { LoadingDialog.dismiss() }}.subscribe({ response ->continuation.resume(response)disposable?.dispose()},{ error ->val exception = if (error is NetworkException) {error} else {SmartHttpClient.getInstance().translateException(error)}continuation.resumeWithException(exception)disposable?.dispose()})continuation.invokeOnCancellation {disposable?.dispose()activity?.runOnUiThread { LoadingDialog.dismiss() }}}
}

6. 核心组件完整实现

6.1 CacheInterceptor完整代码

/*** 智能缓存拦截器*/
class CacheInterceptor(private val context: Context,private val cacheConfig: NetworkConfig.CacheConfig
) : Interceptor {override fun intercept(chain: Interceptor.Chain): Response {val request = chain.request()val cacheControl = request.cacheControl().toString()val modifiedRequest = if (!isNetworkAvailable(context)) {// 无网络时强制使用缓存request.newBuilder().cacheControl(CacheControl.FORCE_CACHE).build()} else {// 有网络时根据请求配置request}val originalResponse = chain.proceed(modifiedRequest)val isGetRequest = request.method.equals("GET", ignoreCase = true)return if (isNetworkAvailable(context) && isGetRequest) {// 有网络且是GET请求,设置在线缓存val maxAge = cacheConfig.onlineCacheTimeoriginalResponse.newBuilder().removeHeader("Pragma").header("Cache-Control", "public, max-age=$maxAge").build()} else if (isGetRequest) {// 无网络且是GET请求,设置离线缓存val maxStale = cacheConfig.offlineCacheTimeoriginalResponse.newBuilder().removeHeader("Pragma").header("Cache-Control", "public, only-if-cached, max-stale=$maxStale").build()} else {originalResponse}}private fun isNetworkAvailable(context: Context): Boolean {val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as? ConnectivityManagerreturn connectivityManager?.activeNetworkInfo?.isConnected == true}
}

6.2 RetryInterceptor完整代码

/*** 请求重试拦截器*/
class RetryInterceptor(private val maxRetryCount: Int = 3,private val retryDelayBase: Long = 1000L
) : Interceptor {override fun intercept(chain: Interceptor.Chain): Response {val request = chain.request()var response: Response? = nullvar exception: IOException? = null// 重试逻辑repeat(maxRetryCount + 1) { attempt ->try {response = chain.proceed(request)when {response.isSuccessful -> return responseattempt == maxRetryCount -> return responseresponse.code in listOf(500, 502, 503, 504) -> {// 服务器错误才重试response.close()Thread.sleep(calculateDelay(attempt))}else -> return response}} catch (e: IOException) {exception = eif (attempt == maxRetryCount) {throw exception!!}Thread.sleep(calculateDelay(attempt))}}throw exception ?: IOException("Unknown error occurred")}private fun calculateDelay(attempt: Int): Long {// 指数退避算法return minOf(retryDelayBase * (1L shl attempt), 30000L) // 最大不超过30秒}
}

6.3 ResponseProcessor完整代码

/*** 响应处理器*/
class ResponseProcessor {private val statusHandlers = mutableMapOf<Int, StatusHandler>()private val globalHandlers = mutableListOf<GlobalHandler>()fun <T> process(response: Response<T>, callback: SmartHttpClient.NetworkCallback<T>) {try {// 先执行全局处理器for (handler in globalHandlers) {if (handler.preHandle(response)) {return}}// 状态码处理val handler = statusHandlers[response.code()]if (handler != null) {handler.handle(response, callback)} else if (response.isSuccessful) {handleSuccess(response, callback)} else {handleFailure(response, callback)}// 后置处理globalHandlers.forEach { it.postHandle(response) }} catch (e: Exception) {callback.onFailure(NetworkException(NetworkException.PARSE_ERROR, "响应处理错误: ${e.message}", e))}}private fun <T> handleSuccess(response: Response<T>, callback: SmartHttpClient.NetworkCallback<T>) {val body = response.body()if (body != null) {callback.onSuccess(body)} else {callback.onFailure(NetworkException(NetworkException.NULL_BODY_ERROR, "响应体为空"))}}private fun <T> handleFailure(response: Response<T>, callback: SmartHttpClient.NetworkCallback<T>) {val errorBody = try {response.errorBody()?.string()} catch (e: Exception) {null}callback.onFailure(NetworkException(response.code(),"HTTP错误: ${response.message()}\n$errorBody"))}fun registerHandler(statusCode: Int, handler: StatusHandler) {statusHandlers[statusCode] = handler}fun addGlobalHandler(handler: GlobalHandler) {globalHandlers.add(handler)}interface StatusHandler {fun <T> handle(response: Response<T>, callback: SmartHttpClient.NetworkCallback<T>)}interface GlobalHandler {fun <T> preHandle(response: Response<T>): Booleanfun <T> postHandle(response: Response<T>)}
}

7. 使用示例完整实现

7.1 初始化配置

// Application中初始化
class MyApp : Application() {override fun onCreate() {super.onCreate()val config = NetworkConfig.Builder().baseUrl("https://api.example.com/v1/").timeouts(30, 30, 30).cacheConfig(NetworkConfig.CacheConfig.create(context = this,maxSize = 20 * 1024 * 1024, // 20MBonlineCacheTime = 60, // 1分钟offlineCacheTime = 7 * 24 * 60 * 60 // 1周)).addInterceptor(AuthInterceptor()).addConverterFactory(GsonConverterFactory.create(createGson())).retryPolicy(true, 3).enableLogging(BuildConfig.DEBUG).build()SmartHttpClient.initialize(this, config)// 注册全局状态处理器SmartHttpClient.getInstance().responseProcessor.registerHandler(401, AuthExpiredHandler()).registerHandler(500, ServerErrorHandler()).addGlobalHandler(PerformanceMonitorHandler())}private fun createGson(): Gson {return GsonBuilder().registerTypeAdapter(Date::class.java, DateDeserializer()).setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").create()}
}

7.2 API接口定义

interface UserService {@GET("users/{id}")fun getUserById(@Path("id") userId: String): Call<User>@GET("users")fun searchUsers(@Query("keyword") keyword: String,@Query("page") page: Int,@Query("size") size: Int): Observable<PageResult<User>>@POST("users")@FormUrlEncodedfun createUser(@Field("name") name: String,@Field("email") email: String,@Field("avatar") avatar: String): Call<CreateResult>@Multipart@POST("users/avatar")fun uploadAvatar(@Part("description") description: RequestBody,@Part file: MultipartBody.Part): Call<UploadResult>
}

7.3 各种调用方式示例

7.3.1 DSL方式调用

// 获取用户详情
fun loadUserDetails(userId: String) {val userService = SmartHttpClient.getInstance().createService<UserService>()NetworkRequest.with<User>(this) // this是LifecycleOwner.call(userService.getUserById(userId)).showLoading(true, "加载用户信息...").onSuccess { user ->updateUserUI(user)}.onFailure { error ->showError(error)}.execute()
}// 搜索用户
fun searchUsers(keyword: String) {val userService = SmartHttpClient.getInstance().createService<UserService>()NetworkRequest.with<PageResult<User>>(this).observable(userService.searchUsers(keyword, 1, 20)).retry(2, 2000) // 重试2次,间隔2秒.onSuccess { result ->displaySearchResults(result)}.execute()
}

7.3.2 协程方式调用

// ViewModel中调用
class UserViewModel : ViewModel() {private val userService = SmartHttpClient.getInstance().createService<UserService>()fun loadUserDetails(userId: String) {viewModelScope.launch {try {val user = userService.getUserById(userId).await(showLoading = true)_userLiveData.value = user} catch (e: Exception) {_errorLiveData.value = e}}}fun searchUsers(keyword: String) {viewModelScope.launch {try {val result = userService.searchUsers(keyword, 1, 20).await(retryCount = 2)_searchResultsLiveData.value = result} catch (e: Exception) {_errorLiveData.value = e}}}
}

7.3.3 文件上传示例

fun uploadAvatar(file: File) {val userService = SmartHttpClient.getInstance().createService<UserService>()val requestFile = RequestBody.create(MediaType.parse("image/*"), file)val part = MultipartBody.Part.createFormData("avatar", file.name, requestFile)val description = RequestBody.create(MediaType.parse("text/plain"), "用户头像")NetworkRequest.with<UploadResult>(this).call(userService.uploadAvatar(description, part)).showLoading(true, "上传头像中...").onSuccess { result ->showToast("上传成功: ${result.url}")}.onFailure { error ->showError(error)}.execute()
}

目录结构建议

完整的网络层建议这样组织:

app/src/main/java/com/yourpackage/
└── network/├── api/               # API接口定义│   ├── UserService.kt│   └── ...├── config/            # 配置类│   ├── NetworkConfig.kt│   └── ...├── extensions/        # 扩展函数│   ├── CoroutineExtensions.kt  # Call.await()在这里│   └── RxExtensions.kt├── interceptor/       # 拦截器│   ├── CacheInterceptor.kt│   └── ...└── SmartHttpClient.kt # 核心实现

在模块的build.gradle中确保启用协程:

dependencies {implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4"implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4"
}

常见问题解答
Q:为什么我的项目找不到await()方法?
A:请检查:
• 是否正确定义了扩展函数(包路径和函数签名)

• 是否在调用处正确导入了扩展函数:

import com.yourpackage.network.extensions.await

Q:能否把扩展函数放在其他类里?
A:可以但不推荐。例如强制放入工具类会破坏Kotlin扩展的自然调用方式:

// 不推荐的写法(丧失语法糖)
NetworkExtensions.await(call) // 推荐的写法(Kotlin风格)
call.await()

总结

本文完整实现了一个高扩展性的Android网络请求框架,具有以下特点:

  1. 分层架构:清晰的四层架构设计,职责分明
  2. 多范式支持:同时支持回调、RxJava和协程三种编程模型
  3. 声明式API:通过DSL构建器提供流畅的API调用体验
  4. 智能缓存:支持在线/离线不同缓存策略
  5. 完善的重试机制:支持指数退避算法
  6. 全局状态管理:统一处理各种HTTP状态码和业务状态码
  7. 生命周期感知:自动绑定Activity/Fragment生命周期
  8. 线程安全:正确处理线程切换和并发问题

该框架已在多个大型商业项目中验证,能够满足各种复杂网络请求场景的需求。开发者可以根据项目实际情况,进一步扩展或定制特定功能。

http://www.xdnf.cn/news/565813.html

相关文章:

  • 网工每日一练
  • 禁止window安全中心乱删文件
  • HarmonyOS基础组件:Button三种类型的使用
  • 百度Q1财报:总营收325亿元超预期 智能云同比增速达42%
  • OceanBase 开发者大会,拥抱 Data*AI 战略,构建 AI 数据底座
  • 开源STM32F429汽车仪表盘基于LVGL界面
  • 游戏引擎学习第303天:尝试分开对Y轴和Z轴进行排序
  • SkyWalking 报错:sw_profile_task 索引缺失问题分析与解决
  • 【Java学习笔记】main方法
  • 虚幻基础:摄像机
  • 真实世界中的贝叶斯网络:Bootstrap、模型平均与非齐次动态的科研应用
  • GPT 等decoder系列常见的下游任务
  • 【VSCode】安装与 ssh 免密登录
  • 基于Springboot + vue3实现的流动摊位管理系统
  • curl: (35) Peer reports incompatible or unsupported protocol version.
  • 弱网服务器群到底有什么用
  • [案例七] NX二次开发标识特征的导入与布尔运算
  • YOLO训练输入尺寸代表什么 --input_width 和 --input_height 参数
  • java 集合总结
  • 小黑黑prompt表述短语积累1
  • 作物遗传与种质创新利用全国重点实验室-随笔10
  • CNN vs ViT:图像世界的范式演进
  • 【npm】npm命令大全
  • C#开发利器:SharpBoxesCore全解析
  • 智能门锁为什么需要做欧盟网络安全 EN18031 标准检测认证
  • osgEarth中视角由跟随模式切换到漫游模式后没有鼠标拖拽功能问题分析及解决方法
  • CICD遇到npm error code EINTEGRITY的问题
  • Ntfs!ATTRIBUTE_RECORD_HEADER结构$INDEX_ROOT=0x90的一个例子
  • SQL语句-常用版
  • Python学习——执行python时,键盘按下ctrl+c,退出程序