在现代 Android 应用开发中,网络编程是必不可少的一部分。Retrofit 是 Square 公司推出的一款类型安全的 HTTP 客户端库,简化了与 RESTful API 的交互。Retrofit 基于 OkHttp,并提供了简洁的接口定义和强大的功能,如异步请求、请求拦截、JSON 解析等。本章节将深入讲解 Retrofit 的基本概念、配置、使用方法以及与 OkHttp 的结合,帮助学员掌握 Retrofit 网络请求的实现。
19.1 网络编程概述
-
网络编程的作用:
- 网络编程用于实现应用与服务器之间的数据交互,例如获取数据、提交数据、更新数据等。
- 常见的网络请求类型有 GET, POST, PUT, DELETE 等。
-
网络编程的挑战:
- 异步操作: 网络请求是异步的,需要处理线程切换和回调。
- 错误处理: 需要处理网络错误、超时、数据解析错误等。
- 安全性: 需要处理 HTTPS、证书验证、加密传输等。
- 性能优化: 需要优化网络请求的性能,例如缓存、重试机制等。
19.2 Retrofit 简介
-
Retrofit 的历史与发展:
- Retrofit 是 Square 公司于 2013 年推出的 HTTP 客户端库。
- Retrofit 基于 OkHttp,提供了更简洁的接口定义和更强大的功能。
- Retrofit 2.0 于 2016 年发布,引入了对协程的支持。
-
Retrofit 的优势:
- 类型安全: Retrofit 使用接口定义 API,提供了类型安全的请求和响应。
- 简洁易用: Retrofit 提供了简洁的 API,易于上手和使用。
- 强大的功能: Retrofit 支持异步请求、请求拦截、JSON 解析、文件上传下载等。
- 可扩展性: Retrofit 可以与 OkHttp 拦截器、转换器等结合使用,实现更强大的功能。
- 协程支持: Retrofit 2.6.0 及以上版本支持 Kotlin 协程,简化异步请求代码。
19.3 Retrofit 的基本使用
19.3.1 添加 Retrofit 依赖
在 build.gradle
文件中添加 Retrofit 依赖:
dependencies {
implementation "com.squareup.retrofit2:retrofit:2.9.0"
implementation "com.squareup.retrofit2:converter-gson:2.9.0"
}
19.3.2 定义 API 接口
使用 Retrofit 的接口定义 API,例如定义一个 GitHub API 接口:
import retrofit2.http.GET
import retrofit2.http.Path
interface GitHubService {
@GET("users/{user}/repos")
suspend fun listRepos(@Path("user") user: String): List<Repo>
}
data class Repo(
val id: Int,
@field:SerializedName("name") val name: String,
@field:SerializedName("html_url") val url: String
)
19.3.3 创建 Retrofit 实例
使用 Retrofit.Builder 创建 Retrofit 实例,并配置基础 URL 和转换器:
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
val retrofit = Retrofit.Builder()
.baseUrl("https://api.github.com/")
.addConverterFactory(GsonConverterFactory.create())
.build()
val service = retrofit.create(GitHubService::class.java)
19.3.4 发起网络请求
使用 Retrofit 发起网络请求,例如获取用户仓库列表:
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
CoroutineScope(Dispatchers.IO).launch {
try {
val repos = service.listRepos("octocat")
// 处理数据
} catch (e: Exception) {
// 处理错误
}
}
19.4 Retrofit 与 OkHttp 的结合
Retrofit 基于 OkHttp,提供了更强大的功能,例如请求拦截、缓存、重试机制等。
19.4.1 使用 OkHttp Interceptor
OkHttp Interceptor 可以在请求发送前或响应返回后拦截请求和响应,进行自定义处理,例如添加请求头、打印日志等。
-
添加请求头:
import okhttp3.Interceptor import okhttp3.OkHttpClient import okhttp3.Request import okhttp3.Response val headerInterceptor = Interceptor { chain -> val original: Request = chain.request() val requestBuilder = original.newBuilder() .header("Accept", "application/json") .method(original.method, original.body) val request: Request = requestBuilder.build() chain.proceed(request) } val okHttpClient = OkHttpClient.Builder() .addInterceptor(headerInterceptor) .build() val retrofit = Retrofit.Builder() .baseUrl("https://api.github.com/") .client(okHttpClient) .addConverterFactory(GsonConverterFactory.create()) .build()
-
打印日志:
import okhttp3.logging.HttpLoggingInterceptor val loggingInterceptor = HttpLoggingInterceptor() loggingInterceptor.level = HttpLoggingInterceptor.Level.BODY val okHttpClient = OkHttpClient.Builder() .addInterceptor(loggingInterceptor) .build()
19.4.2 使用 OkHttp Cache
OkHttp 提供了缓存机制,可以缓存网络请求结果,提高应用性能。
-
配置缓存:
import okhttp3.Cache import java.io.File val cacheSize = 10 * 1024 * 1024 // 10 MB val cacheDirectory = File(context.cacheDir, "http-cache") val cache = Cache(cacheDirectory, cacheSize) val okHttpClient = OkHttpClient.Builder() .cache(cache) .build()
-
配置缓存策略:
import okhttp3.CacheControl val request = Request.Builder() .url("https://api.github.com/users/octocat/repos") .cacheControl(CacheControl.Builder() .maxStale(1, TimeUnit.DAYS) .build()) .build()
19.5 Retrofit 进阶功能
19.5.1 文件上传与下载
-
文件上传:
@Multipart @POST("upload") suspend fun uploadFile( @Part file: MultipartBody.Part, @Part("description") description: RequestBody )
-
文件下载:
@GET suspend fun downloadFile(@Url fileUrl: String): ResponseBody // 下载文件 val response = service.downloadFile("https://example.com/file.zip") val file = File(context.filesDir, "file.zip") response.body()?.byteStream()?.use { input -> file.outputStream().use { output -> input.copyTo(output) } }
19.5.2 错误处理
- 自定义异常:
class ApiException(message: String, val code: Int) : Exception(message) // 解析错误 try { val response = service.getData() if (response.isSuccessful) { // 处理成功 } else { throw ApiException("API Error", response.code()) } } catch (e: ApiException) { // 处理 API 异常 } catch (e: Exception) { // 处理其他异常 }
19.6 实战案例
-
案例一:使用 Retrofit 实现 GitHub API 请求
- 定义 GitHub API 接口。
- 创建 Retrofit 实例。
- 使用协程发起网络请求,获取用户仓库列表。
- 在 Activity 中显示仓库列表。
-
案例二:使用 Retrofit 实现文件上传
- 定义文件上传 API 接口。
- 使用 Retrofit 上传文件。
- 在 Activity 中选择文件并上传。
-
案例三:使用 Retrofit 实现文件下载
- 定义文件下载 API 接口。
- 使用 Retrofit 下载文件。
- 在 Activity 中下载文件并保存到内部存储。
19.7 课后作业
-
任务一:使用 Retrofit 实现 GitHub API 请求
- 定义 GitHub API 接口。
- 创建 Retrofit 实例。
- 使用协程发起网络请求,获取用户仓库列表。
- 在 Activity 中显示仓库列表。
-
任务二:使用 Retrofit 实现文件上传
- 定义文件上传 API 接口。
- 创建 Retrofit 实例。
- 使用协程发起文件上传请求。
- 在 Activity 中选择文件并上传。
-
任务三:使用 Retrofit 实现文件下载
- 定义文件下载 API 接口.
- 创建 Retrofit 实例.
- 使用协程发起文件下载请求.
- 在 Activity 中下载文件并保存到内部存储.
通过本章节的学习,学员将能够掌握 Retrofit 网络请求的基本概念、使用方法以及与 OkHttp 的结合,并能够使用 Retrofit 实现各种网络请求操作,包括 GET, POST, 文件上传下载等。