retrofit的用法
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
retrofit的用法
Retrofit 是一款用于 Android 平台的类型安全的HTTP 客户端,它的设计理念是简洁、易用、可读性好,不断引用着许多其他库的优势,从而成为了大家使用Android 网络请求的首选。
那么,本文将为大家介绍Retrofit 在 Android 中的使用方法和一些需要注意的细节,以便开发者快速、准确地对其进行应用。
## 1、基础环境和依赖
在通过 Retrofit 进行网络请求时,我们需要事先导入相关的依赖库,包括网络请求所依赖的 OkHttp 库、由于 Retrofit 库本质上是基于反射的,所以还需要导入Retrofit 的反射库:
```gradle implementation
'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0' implementation
'com.squareup.okhttp3:logging-interceptor:4.9.1'
```
其中,`converter-gson` 是用于数据解析的库,这在后面的请求部分中进行了详细解释。
`logging-
interceptor` 库用于记录网络请求和响应时的日志信息,
方便开发者进行调试。
## 2、请求定义
在使用 Retrofit 进行网络请求时,我们通常需要先
定义请求接口,这些请求接口对应服务端 API 接口的
URL、请求方式、请求头、请求参数等信息。
定义请求接
口时,开发者可以采用注解的方式来减少代码的编写,但
是需要注意的是,Retrofit 中的每个注解都有其特定的作
用,而且注解的用法和顺序对请求的参数以及请求方式有
影响。
下面是一段 GET 请求接口的示例代码:
```java public interface ApiService
{ @GET("api/login") Call<User>
login(@Query("username") String username, @Query("password") String password); } ```
其中,注解`@GET`指定了 API 接口的请求方式为 GET
请求,括号里面的字符串是接口路径。
注解`@Query`表示
请求的参数,比如 username 参数和 password 参数。
这
个示例接口返回的数据是一个 `Call<User>` 对象,
`Call` 是 Retrofit 创建的请求对象,它有许多方法对
HTTP 请求进行设置和执行,比如设置请求头、请求体、超
时时间等等。
## 3、数据解析和错误处理
在定义了请求接口后,我们还需要定义数据解析。
Retrofit 是支持多种数据格式的解析的,包括 GSON、
Jackson、Moshi 等。
通常情况下我们使用 GSON 解析器,
它非常的快速和简单。
那么,我们添加了对
`GsonConverterFactory` 的支持,代码如下:
```java public static <T> T
createService(Class<T> serviceClass) { // 创建
using gson converter Gson gson = new
GsonBuilder() .setLenient()
.create(); Retrofit retrofit = new
Retrofit.Builder() .baseUrl(baseUrl) .client(initOkhttpClient()) .addConver terFactory(GsonConverterFactory.create(gson)) .build(); return
retrofit.create(serviceClass); } ```
这是一个实例方法,用于创建 `ApiService` 接口的
实例对象。
在方法内部,我们首先创建了一个 GSON 解析
器,然后创建了一个 Retrofit 实例,添加了 GSON 转换
器,从而使请求数据能够自动转换为我们定义的对象类
型。
但是,在后端服务器的数据返回和网络请求环节,难
免会出现 HTTP 状态码错误、解析异常、网络连接超时等
问题。
对于这些错误情况,我们可以使用 Retrofit 的异
常处理器来进行处理。
下面是一个实例代码,用于处理
HTTP 状态码为 4xx 或 5xx 的异常:
```java public class ServerErrorResponse
{ private int code; private String message;
// 省略 getter 和 setter }
public class ErrorHandlingConverter extends
Converter.Factory {
public static ErrorHandlingConverter
create() { return new
AutoValueGson_ErrorHandlingConverter(GsonParser.def aultGsonParser()); }
@Override public @Nullable
Converter<ResponseBody, ?>
responseBodyConverter(Type type, Annotation[]
annotations, Retrofit retrofit)
{ Converter<ResponseBody, ?>
delegateConverter =
retrofit.nextResponseBodyConverter(this, type, annotations); return
(Converter<ResponseBody, ServerErrorResponse>) body
-> { ResponseBody responseBody =
delegateConverter.convert(body); if (responseBody != null) { try
{ JSONObject jsonObject = new
JSONObject(responseBody.string());
int status = jsonObject.optInt("status", -1); if (status >= 400) { String
message = jsonObject.optString("message", "unknown
error"); return new ServerErrorResponse(status,
message); } }
catch (Exception e) { throw new IOException(e); } } return new ServerErrorResponse(-1, "unknown
error"); }; } } ```
在这里,我们创建了一个自定义的
`ErrorHandlingConverter` 类,它实现了 Retrofit 的
`Converter.Factory` 接口,用于处理网络请求的异常信
息。
方法 `responseBodyConverter()` 是用于解析返回
响应数据的,其中的转换器委托了 Retrofit 的原始转换
器执行,如果发现响应状态码不是 200,则解析响应体中
的异常信息,将其封装为 `ServerErrorResponse` 类型,
该类是我们自己定义的一个异常数据结构。
当然,如果发
现解析出的响应体没有正确的 JSON 格式,也会抛出解析异常。
## 4、网络请求执行和回调处理
接下来,我们需要执行前面定义的网络请求和解析,从而获得数据。
Retrofit 中提供了两个执行请求的方法,分别是 `execute()` 和 `enqueue()`。
其中,
`execute()` 是同步请求,通常在子线程中执行,而
`enqueue()` 是异步请求,内部使用了 OkHttp 的异步的方式执行请求,通常在主线程中执行。
在定义方法时,我们通常选择使用 `enqueue()` 方法。
为了方便处理请求结果,我们在调用异步执行时,还需要设置一个回调接口,例如:
```java public interface ApiCallback<T>
{ void onSuccess(ApiResponse<T> response);
void onFailure(Throwable t); }
public class ApiResponse<T> { private int statusCode; private T body;
public ApiResponse(int statusCode, T body) { this.statusCode = statusCode; this.body = body; }
// 省略 getter 和 setter } ```
这里,我们定义了一个 `ApiCallback` 接口,用于回调网络请求的结果。
类型 `T` 表示响应数据的类型,我们在 `ApiResponse` 类中封装了响应状态码和响应体。
下面是一个典型的网络请求,用于登录的请求方法。
我们使用了 `enqueue()` 异步执行请求,对应了
`ApiCallback` 接口中的 `onSuccess()` 和
`onFailure()` 方法,从而将请求结果绑定到 UI 界面。
在调用 `ApiService.login()` 时,其中作为参数的
`Callback` 对象是 Retrofit 自己定义的一个回调接口类型。
```java public void login(String username, String password, ApiCallback<User> callback)
{ ApiService apiService =
createService(ApiService.class);
apiService.login(username, password).enqueue(new Callback<User>() { @Override public void onResponse(Call<User> call, Response<User> response) { if
(response.isSuccessful())
{ callback.onSuccess(new ApiResponse<>(response.code(),
response.body())); } else
{ try { String
errorBody = response.errorBody().string(); callback.onFailure(new
ApiException(errorBody)); } catch (IOException e)
{ e.printStackTrace(); callback.onFailure(e); }
} }
@Override public void
onFailure(Call<User> call, Throwable t)
{ callback.onFailure(t); }
}); } ```
在响应到服务端请求数据之前,我们可以设置相关的
请求头,下面是一段设置请求头的示例代码:
```java public static OkHttpClient
initOkhttpClient() { OkHttpClient.Builder
builder = new
OkHttpClient.Builder() .writeTimeout(10
, TimeUnit.SECONDS) .readTimeout(15,
TimeUnit.SECONDS) .connectTimeout(10,
TimeUnit.SECONDS) .retryOnConnectionFai
lure(true); builder.addInterceptor(chain ->
{ Request originalRequest =
chain.request(); Request.Builder builder1 = originalRequest.newBuilder() .heade r("Content-Type", "application/json"); Request request = builder1.build(); return chain.proceed(request); });
return builder.build(); } ```
这里我们创建了一个 OkHttpClient 实例,使用了Builder 模式设置了超时时间,还添加了一个
Interceptor(拦截器),用于在请求头中添加了一个Content-Type 值为 application/json,表示请求的数据是 JSON 格式的数据。
## 结论
在这篇文章中,我们详细介绍了 Retrofit 的使用方法和注意事项,并通过示例代码演示了如何定义请求接口、解析数据、处理异常、执行网络请求和回调。
Retrofit 是一个强大、简单易用的网络请求库,在Android 开发中广泛使用,它的设计思想不仅体现了RESTful 服务,还强调了类型安全、注解的优雅编码风格以及良好的易用性。
如果你在开发 Android 应用程序时需要进行网络请求,不妨尝试使用 Retrofit 来提高开发速度。