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]
// ... 处理其他结果

最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



