Retrofit的使用

添加权限

manifest文件添加网络权限

<uses-permission android:name="android.permission.INTERNET"/>

添加依赖

主库

dependencies {
implementation ‘com.squareup.retrofit2:retrofit:2.0.2’// Retrofit库
}

扩展数据转换器

如请求类型和json模型的互转(此依赖一般都要添加):
implementation ‘com.squareup.retrofit2:converter-gson:2.0.2’

其他如下:

数据解析器Gradle依赖
Gson:converter-gson:2.0.2
Jackson:converter-jackson:2.0.2
Simple XML:converter-simplexml:2.0.2
Protobuf:converter-protobuf:2.0.2
Moshi:converter-moshi:2.0.2
Wire:converter-wire:2.0.2
Scalars:converter-scalars:2.0.2

扩展调用适配器(CallAdapter)

retrofit除了内置默认的DefaultCallAdapterFactory,支持调用服务方法返回类型Call外,
也支持其他网络请求适配器方式:guava、Java8和rxjava。

适配器简称依赖路径支持的返回类型
guava:adapter-guava:2.0.2
Java8:adapter-java8:2.0.2
rxjava:adapter-rxjava:2.0.2Observable、Flowable等

创建 接收服务器返回数据 的模型

如:

public class AppRequestResult<T> {
   private int code;
   private T data;
   private String msg;
}

创建 用于描述网络请求 的接口

你需要定义一个接口,然后在该接口内定义用来描述请求的方法,如:

public interface Api {}

以下第一类的注解用于标注方法的请求方式,如get、post等。第二类的注解用于标注请求数据的组织方式。第三类注解用于标注不同的数据。
根据接口的请求方法查看下面对应的注解的使用介绍,如get请求方式的接口请查看@Get的内容。

请求地址的构成

一个请求的URL可以通过 替换块 和 请求方法的参数 实现动态更新。网络请求的完整 Url =在创建Retrofit实例时通过.baseUrl()设置的基本url(以下称预置的基本url) +网络请求接口的注解设置(下面称 “path“ ),但是当path中包含完整的url地址时(以http开头),请求时预置的基本url会被忽略。

无请求体的请求方式:DELETE、GET、HEAD、OPTIONS。
有请求体的请求方式:PATCH、POST、PUT。

第一类:HTTP请求方法

@HTTP

作用:替换**@GET、@POST、@PUT、@DELETE、@HEAD**注解的作用 及 更多功能拓展
具体使用:通过属性method、path、hasBody进行设置
例子:

/**
     * method:网络请求的方法(区分大小写)
     * path:网络请求地址路径
     * hasBody:是否有请求体
     */
    @HTTP(method = "GET", path = "blog/{id}", hasBody = false)
    Call<ResponseBody> getCall(@Path("id") int id);
    // {id} 表示是一个变量
    // method 的值 retrofit 不会做处理,所以要自行保证准确

@Get

get请求。假设baseUrl=http://192.168.43.173/api/。
1、没有参数:http://192.168.43.173/api/trades
@GET(“trades”)
Call getItem();
2、URL中带有参数:http://192.168.43.173/api/trades/{userId}
@GET(“trades/{userId}”)
Call getItem(@Path(“userId”) String userId);
3、参数在url问号之后:http://192.168.43.173/api/trades?userId={用户id}
@GET(“trades”)
Call getItem(@Query(“userId”) String userId, @QueryMap Map<String, String> map);

@Post

post请求。
1、补全url和url后的参数,添加一条表单数据:
http://192.168.43.173/api/trades/{userId}?token={token}
@FormUrlEncoded
@POST(“trades/{userId}”)
Call postResult(@Path(“userId”) String userId, @Query(“token”) String token, @Field(“reason”) String reason);
2、post一个对象
1)@POST(“trades”)
Call postResult(@Body TradesBean bean);
2)@POST(“trades/{userId}”)
Call postResult(@Part(“entity”) TradesBean bean);

@Put

put请求
1、put一个实体
@PUT(“trade/carInfo/{pid}”)
Call putInfo(
@Path(“pid”) Int pid,
@Body CarInfoBean carInfoBean;)

@Delete

方法注解。DELETE请求。
例子:补全路径。
@DELETE(“trades/{userId}”)
Call deleteInfo(
@Path(“userId”) String userId,
@Query(“token”) String token);

@HEAD

方法注解。HEAD请求。

@PATCH

方法注解。PATCH请求。

@OPTIONS

方法注解。OPTIONS请求。

第二类:标记类

@FormUrlEncoded

作用:表示请求体是一个表单。每个键值对需要用@Filed来注解键名,随后的对象需要提供值。
@POST(“form”)
@FormUrlEncoded
Call request(@Field(“username”) String name, @Field(“age”) int age);
注意:不能与@Multipart注解一起用。

@Multipart

作用:表示请求体是多部分组成。
@POST("/form")
@Multipart
Call testFileUpload1(@Part(“name”) RequestBody name, @Part(“age”) RequestBody age, @Part MultipartBody.Part file);
注意:不能与@FormUrlEncoded注解一起用。

@Streaming

作用:表示将响应体的数据以流的形式返回;适用于返回数据较大的场景。如果没有使用该注解,默认把数据载入内存,之后数据也是从内存读取。

第三类:参数类

@Header & @Headers

作用:@Header为参数注解。@Headers为方法注解。添加请求头 &添加不固定的请求头。
例子:
@GET(“user”)
Call getUser(@Header(“Authorization”) String authorization)

//@Headers(“Cache-Control: max-age=640000”)
@Headers({
“X-Foo: Bar”,
“X-Ping: Pong”
})
@GET("/")

注意:声明1个以上的@Headers注解会导致其中一个无效。值格式:”name1:value1”,”name2:value2”。当存在name为Content-Type的header时,会修改整个请求的MediaType。

@HeaderMap

例子:
@GET("/search")
void list(@HeaderMap Map<String, String> headers);
注意:后面跟随的类型必须是Map,且key类型必须为String。

@Body

作用:当你想直接控制POST/PUT请求的请求体,此对象会使用retrofit的转换器序列化然后直接设置到请求的请求体。
注意:不能和@FormUrlEncoded和@Multipart一起使用。一个方法内只能声明一个该注解。

@Field & @FieldMap

作用:用于表单字段
具体使用:只能与 @FormUrlEncoded 注解配合使用,参数类型可以是Iterable<具体类型>、具体类型[]或具体类型。FieldMap接受的类型是Map<String, String>,非String类型会调用其toString方法。
@POST("/form")
@FormUrlEncoded
Call testFormUrlEncoded1(@Field(“username”) String name, @Field(“age”) int age);
@POST("/form")
@FormUrlEncoded
Call testFormUrlEncoded2(@FieldMap Map<String, String> map);
注意:@FieldMap后面跟随的类型必须是Map,且key类型必须为String。

@Part & @PartMap

作用:必须与 @Multipart 注解配合使用,适合有文件上传的场景。与@Field的区别:功能相同,但携带的参数类型更加丰富,包括数据流。
当@Part的名称值为空时,后面的类型可以是Iterable<MultipartBody.Part>、MultipartBody.Part[]、MultipartBody.Part。当@Part的名称有值时,用于提交表单数据,后面的类型可以是MultipartBody.Part之外的其他类型,如Iterable、String[]、String。
@Multipart
@POST("/")
Call example(
@Part(“description”) String description,
@Part(value = “image”, encoding = “8-bit”) RequestBody image);
当值类型是 okhttp3.MultipartBody.Part时,其内容会被直接使用。当值类型为RequestBody时,会直接使用他的内容类型,名称取注解声明的。其他类型会被转换器转换成合适的表示,名称取注解声明的。

@PartMap 注解后面的类型必须是Map<String, MultipartBody.Part之外的其他类型>。
@Multipart
@POST("/upload")
Call upload(
@Part(“file”) RequestBody file,
@PartMap Map<String, RequestBody> params);
当值类型为RequestBody时,会直接使用他的内容类型。其他类型会被转换器转换成合适的表示。map类型的key-value都不能为null。

@Query和@QueryMap

作用:用于 @GET 方法的查询参数。如:http://www.println.net?cate=android中的查询参数cate。
具体使用:配置时只需要在接口方法中增加一个参数即可:
@GET(“abc”)
Call cate(@Query(“cate”) String cate, @QueryMap Map<String, String> map);
注意:后面跟随的类型如果是List等列表,则必须指定泛型的具体类型,如List。
@QueryMap跟随的类型必须是Map类型,且key类型必须为String。

@QueryName

指定url的?后没有值的查询参数名称。

1、简单示例:
@GET("/friends")
Call friends(@QueryName String filter);
使用foo.friends(“contains(Bob)”)调用会产生/friends?contains(Bob) 。
2、数组/可变参数示例:
@GET("/friends")
Call friends(@QueryName String… filters);
调用foo.friends(“contains(Bob)”, “age(42)”)产生/friends?contains(Bob)&age(42) 。
3、默认情况下,参数名称是 URL 编码的。 指定encoded=true以更改此行为。
@GET("/friends")
Call friends(@QueryName(encoded=true) String filter);
使用foo.friends(“name+age”))调用会产生/friends?name+age 。

@Path

作用:URL地址的缺省值
具体使用:
@GET(“users/{u}/repos”)
Call getBlog(@Path(“u”) String user );
注意:@Path不能和@Url一起使用。不能在@Query、@QueryName、@QueryMap之后声明。存在@Path声明时,方法注解后的url不能为空。

@Url

值:okhttp3.HttpUrl, String, java.net.URI, or android.net.Uri其中一种类型。
作用:绝对或相对url。
使用:
@GET
Call testUrlAndQuery(@Url String url, @Query(“showAll”) boolean showAll);
注意:@Path不能和@Url一起使用。不能在@Query、@QueryName、@QueryMap之后声明。当有@Url时,@GET后面的URL必须为空。

其他类

@Tag

为请求打上标签
@GET("/")
Call foo(@Tag String tag);
注意:一个方法可设置多个不同类型参数的标签,不允许出现重复类型的@Tag。

创建 Retrofit 实例

OkHttpClient.Builder builder = new OkHttpClient.Builder()
                .addInterceptor(this.publicParamInterceptor)
                .addInterceptor(logInterceptor);
                
        this.retrofit = new Retrofit.Builder()
                .addConverterFactory(GsonConverterFactory.create())
                //.addCallAdapterFactory(RxJavaCallAdapterFactory.create())//需要方法返回Observable时使用
                .client(builder.build())
                .baseUrl(baseUrl)
                .validateEagerly(true)
                .build();

可设置参数

请求客户端
用于请求的客户端。这是一个调用callFactory的方便方法。
client(OkHttpClient client)

调用工厂(请求客户端的接口)
为创建Call实例指定一个自定义的调用工厂。
callFactory(okhttp3.Call.Factory factory)

API基本url
应该以”/”结尾。具体见注释。
baseUrl(URL baseUrl)

转换工厂
用于对象的序列化和反序列化。
addConverterFactory(Converter.Factory factory)

调用适配器工厂
用于支持服务方法返回除了Call以外的类型。
addCallAdapterFactory(CallAdapter.Factory factory)

回调执行器
从你的服务方法返回Call时,执行器在Callback方法中被调用。
callbackExecutor(Executor executor)

是否马上验证
validateEagerly(boolean validateEagerly)。是否在调用create(Class)创建接口实例时就检测接口的方法定义地是否正确,而不是在调用方法时才检测。默认false。

创建 网络请求接口实例

Api api = retrofit.create(Api.class);

发送网络请求(异步 / 同步)

Call<RequestResult> call = api.getA(...);
//发送网络请求(异步)
call.enqueue(new Callback<Translation>() {
            //请求成功时回调
            @Override
            public void onResponse(Call<Translation> call, Response<Translation> response) {
                //请求处理,输出结果
                response.body().show();
            }

            //请求失败时候的回调
            @Override
            public void onFailure(Call<Translation> call, Throwable throwable) {
                System.out.println("连接失败");
            }
        });

// 发送网络请求(同步)
Response<RequestResult> response = call.execute();

扩展

自定义Converter

参考GsonConverterFactory类的实现。

Retrofit retrofit = new Retrofit.Builder()
		...
      // 我们自定义的一定要放在其他的Converter前面
      .addConverterFactory(GsonConverterFactory.create())
      .build();

注:addConverterFactory是有先后顺序的,如果有多个ConverterFactory都支持同一种类型,那么就是只有第一个才会被使用,而GsonConverterFactory是不判断是否支持的,所以这里若交换了顺序还会有一个异常抛出,原因是类型不匹配。

自定义CallAdapter

参考RxJavaCallAdapterFactory类。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值