Android开发实战班 -网络编程 - Retrofit 网络请求 + OkHttp 使用详解

在现代 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 依赖:

groovy 复制代码
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 接口:

kotlin 复制代码
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 和转换器:

kotlin 复制代码
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 发起网络请求,例如获取用户仓库列表:

kotlin 复制代码
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 可以在请求发送前或响应返回后拦截请求和响应,进行自定义处理,例如添加请求头、打印日志等。

  • 添加请求头:

    kotlin 复制代码
    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()
  • 打印日志:

    kotlin 复制代码
    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 提供了缓存机制,可以缓存网络请求结果,提高应用性能。

  • 配置缓存:

    kotlin 复制代码
    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()
  • 配置缓存策略:

    kotlin 复制代码
    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 文件上传与下载
  • 文件上传:

    kotlin 复制代码
    @Multipart
    @POST("upload")
    suspend fun uploadFile(
        @Part file: MultipartBody.Part,
        @Part("description") description: RequestBody
    )
  • 文件下载:

    kotlin 复制代码
    @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 错误处理
  • 自定义异常 :

    kotlin 复制代码
    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 实战案例

  1. 案例一:使用 Retrofit 实现 GitHub API 请求

    • 定义 GitHub API 接口。
    • 创建 Retrofit 实例。
    • 使用协程发起网络请求,获取用户仓库列表。
    • 在 Activity 中显示仓库列表。
  2. 案例二:使用 Retrofit 实现文件上传

    • 定义文件上传 API 接口。
    • 使用 Retrofit 上传文件。
    • 在 Activity 中选择文件并上传。
  3. 案例三:使用 Retrofit 实现文件下载

    • 定义文件下载 API 接口。
    • 使用 Retrofit 下载文件。
    • 在 Activity 中下载文件并保存到内部存储。

19.7 课后作业

  1. 任务一:使用 Retrofit 实现 GitHub API 请求

    • 定义 GitHub API 接口。
    • 创建 Retrofit 实例。
    • 使用协程发起网络请求,获取用户仓库列表。
    • 在 Activity 中显示仓库列表。
  2. 任务二:使用 Retrofit 实现文件上传

    • 定义文件上传 API 接口。
    • 创建 Retrofit 实例。
    • 使用协程发起文件上传请求。
    • 在 Activity 中选择文件并上传。
  3. 任务三:使用 Retrofit 实现文件下载

    • 定义文件下载 API 接口.
    • 创建 Retrofit 实例.
    • 使用协程发起文件下载请求.
    • 在 Activity 中下载文件并保存到内部存储.

通过本章节的学习,学员将能够掌握 Retrofit 网络请求的基本概念、使用方法以及与 OkHttp 的结合,并能够使用 Retrofit 实现各种网络请求操作,包括 GET, POST, 文件上传下载等。

相关推荐
zhao3266857512 小时前
如何有效利用数据采集HTTP代理
网络·网络协议·http
单片机社区4 小时前
随笔十七、eth0单网卡绑定双ip的问题
网络·嵌入式硬件·网络协议·udp·智能路由器
安静的做,安静的学4 小时前
网络仿真工具Core环境搭建
linux·网络·网络协议
小度爱学习7 小时前
数据链路层协议
运维·服务器·网络·网络协议·网络安全
龙之叶7 小时前
Android13源码下载和编译过程详解
android·linux·ubuntu
Ciderw9 小时前
TCP三次握手和四次挥手
开发语言·网络·c++·后端·网络协议·tcp/ip·golang
闲暇部落9 小时前
kotlin内联函数——runCatching
android·开发语言·kotlin
大渔歌_9 小时前
软键盘显示/交互问题
android
爱吃喵的鲤鱼10 小时前
Linux——网络(udp)
linux·网络·udp
乐茵安全10 小时前
《网络安全中的“泛洪”攻击:揭秘、防范与应对策略》
服务器·网络·web安全