Android 网络请求:多功能网络请求库

Android 网络请求:多功能网络请求库

介绍

这是一个基于现代Android技术栈的网络请求库示例项目,集成了OkHttp、Retrofit和Kotlin Flow,提供了一套完整的网络请求解决方案。项目展示了如何在Android应用中优雅地处理网络请求,包括基本请求、接口缓存、文件上传下载、断点续传等高级功能。

核心特性

  • 现代化架构:基于OkHttp + Retrofit + Kotlin Flow构建
  • 双重API风格:支持Flow响应式编程和传统挂起函数两种方式
  • 统一错误处理:提供一致的错误处理机制
  • 文件操作支持:完整的文件上传、下载和断点续传功能
  • 模块化设计:网络层高度封装,便于复用和维护
  • 多种数据格式:支持JSON对象、原始字符串等多种响应格式
  • 多个服务器支持:支持配置多个服务器地址,请求不同服务器数据

软件架构

app
├── base          # 基础组件
├── bean          # 数据模型
├── net           # 网络层核心
│   ├── api       # API接口定义
│   ├── base      # 基础响应类
│   └── ext.kt    # 扩展函数
├── ui            # 界面层
└── vm            # ViewModel层

功能演示

项目包含三个主要功能演示页面:

1. Flow风格请求 (FlowRequestActivity)

  • 基础响应式请求(BaseResponse格式)
  • 对象响应式请求(直接解析为对象)
  • 字符串响应式请求(原始数据)
  • 组合多个API请求

2. 挂起函数风格请求 (SuspendRequestActivity)

  • 传统挂起函数方式请求
  • 同步风格的数据获取
  • 多请求组合处理

3. 文件操作 (FileOperationActivity)

  • 文件选择和上传
  • 普通文件下载
  • 断点续传下载
  • 文件信息获取

使用说明

1. 初始化网络库

在Application中初始化网络模块:
多服务器配置

class MyApplication : Application() {
   
   
   override fun onCreate() {
   
   
      super.onCreate()

      // 初始化网络模块
      val server1Config = HttpConfig(serverUrl = server1Url, cacheDir = cacheDir)
      HttpClient.init(server1Url, server1Config)

      // 初始化网络模块
      val server2Config = HttpConfig(serverUrl = server2Url)
      HttpClient.init(server2Config)

      // 初始化网络模块
      HttpClient.init(server3Url)
   }
}

2. 定义API接口

/**
 * @author jiangtao on 2025/9/20
 * 网络请求API接口定义
 * 定义了应用程序所需的各种网络请求方法
 */
interface ApiService {
   
   
   /**
    * 查询域名的Whois信息
    * @param domain 域名参数
    * @return 返回封装了Whois信息的BaseResponse对象
    */
   @GET("/api/whois")
   @Cacheable(
       ttl = 30 * 1000,
       strategy = CacheStrategy.CACHE_FIRST,
       includeQueryParams = true
   )
   suspend fun whois(@Query("domain") domain: String): BaseResponse<Whois?>?

   /**
    * 查询城市天气信息
    * @param city 城市名称参数
    * @return 返回天气信息对象
    */
   @GET("/api/weather")
   suspend fun tianqi(@Query("city") city: String): Tianqi

   /**
    * 获取美女图片信息(示例接口)
    * @return 返回任意类型的数据
    */
   @GET("/api/pcmeinvpic")
   suspend fun pcmeinv(): Any?
}

2.1 动态添加请求头
interface ApiService {
   
   
    @Headers("X-Force-Network: true")
    @GET("users")
    suspend fun getUsersForceNetwork(): BaseResponse<List<User>>
}
interface ApiService {
   
   
    @GET("users")
    suspend fun getUsers(@Header("X-Force-Network") forceNetwork: Boolean = false): BaseResponse<List<User>>
}

// 使用时强制从网络获取
apiService.getUsers("true")

3. 创建Repository

/**
 * @author jiangtao on 2025/9/20
 * 网络请求仓库类
 * 继承自NetRepository,提供应用程序所需的网络请求方法
 * 包含Flow风格和普通挂起函数风格的网络请求方法
 */
class MyNetworkRepository : NetworkRepository {
   
   

   /**
    * 创建单个实例
    */
   private val service = RetrofitClient.create(server1Url)
   private val apiService1 = service.createService(ApiService::class.java)
   private val apiService2 = service.createService<ApiService>()
   //请求返回非json数据
   private val apiService3 = service.createService<ApiService>(false)

   /**
    * 通过 HttpClient 从 Application创建的实例获取
    */
   // 注入具体的API服务
   private val apiService: ApiService = HttpClient.createService(server1Url)
   //用于请求返回非json数据
   private val rawApiService = HttpClient.createService<RawApiService>(server1Url, false)
   private val fileApiService = HttpClient.createService(server1Url, FileApiService::class.java)

   // ===================================================================
   // Flow 风格的网络请求方法
   // ===================================================================

   /**
    * 查询域名信息
    * @param domain 域名
    * @return 返回包含Whois信息的Flow
    */
   fun whois(domain: String): Flow<FlowResult<BaseResponse<Whois?>?>> = apiCall {
   
   
      apiService.whois(domain)
   }

   /**
    * 查询天气信息
    * @param city 城市名
    * @return 返回包含天气信息的Flow
    */
   fun tianqi(city: String): Flow<FlowResult<Tianqi?>> {
   
   
      return apiCall {
   
   
         apiService.tianqi(city)
      }
   }

   /**
    * 获取美女图片接口(示例接口)
    * @return 返回图片数据的Flow
    */
   fun pcmeinv(): Flow<FlowResult<String?>> {
   
   
      return apiCall {
   
   
         rawApiService.pcmeinv()
      }
   }

   // ===================================================================
   // 普通挂起函数风格的网络请求方法
   // ===================================================================

   /**
    * 同步风格的挂起函数 - 查询域名信息
    * @param domain 域名
    * @return 返回Whois信息的BaseResponse包装对象
    */
   suspend fun getWhoIsInfo(domain: String): BaseResponse<Whois?>? {
   
   
      // 这里应该是实际的 API 调用
      return apiService.whois(domain)
   }

   /**
    * 同步风格的挂起函数 - 查询天气信息
    * @param city 城市名
    * @return 返回天气信息对象
    */
   suspend fun getTianqiInfo(city: String): Tianqi? {
   
   
      // 这里应该是实际的 API 调用
      return apiService.tianqi(city)
   }

   /**
    * 同步风格的挂起函数 - 获取美女图片接口
    * @return 返回图片数据字符串
    */
   suspend fun getPcmeinvInfo(): String? {
   
   
      // 这里应该是实际的 API 调用
      return rawApiService.pcmeinv()
   }

   suspend fun fetchMultipleDataDirect(domain: String, city: String): MultipleDataResult {
   
   
      // 并行执行所有API调用
      val whoisResult = apiService.whois(domain)
      val tianqiResult = apiService.tianqi(city)
      val pcmeinvResult = rawApiService.pcmeinv()

      // 等待所有结果
      val whoisData = whoisResult?.data
      val tianqiData = tianqiResult
      val pcmeinvData = pcmeinvResult

      // 组合结果并返回
      return MultipleDataResult(whoisData, tianqiData, pcmeinvData)
   }

   /**
    * 合并多个网络请求结果的Flow方法
    */
   fun fetchMultipleData(domain: String, city: String): Flow<FlowResult<MultipleDataResult?>> =
      combineApiCalls(
         {
   
    getWhoIsInfo(domain) },
         {
   
    getTianqiInfo(city) },
         {
   
    getPcmeinvInfo() },
         // ... 可以继续添加更多API调用
      ) {
   
    results ->
         // 在这里处理所有结果并组合成最终数据
         val data1 = results[0] as? BaseResponse<Whois?>?
         val data2 = results[1] as? Tianqi
         val data3 = results[2]
         // ... 处理其他结果

         MultipleDataResult(data1?.data, data2, data3)
      }

   /**
    * 使用Flow方式合并多个网络请求结果
    */
   fun fetchMultipleDataWithFlow(
      domain: String,
      city: String
   ): Flow<FlowResult<MultipleDataResult>> =
      combineFlows(
         whois(domain),
         tianqi(city),
         pcmeinv(),
         // ... 添加更多Flow
      ) {
   
    results ->
         // 在这里处理所有结果并组合成最终数据
         val data1 = results[0] as? BaseResponse<Whois?>?
         val data2 = results[1] as? Tianqi
         val data3 = results[2]
         // ... 处理其他结果

         
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

laujiangtao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值