它是Square公司开发的现在非常流行的网络框架
性能好,处理快,使用简单,Retrofit 是安卓上最流行的HTTP Client库之一
默认使用OKHttp处理网络请求,我觉得可以看成是OKHttp的增强。默认使用Gson解析.
//配置retrofit2.0
compile 'com.squareup.retrofit2:retrofit:+'
compile 'com.squareup.retrofit2:converter-gson:+'
//配置支持Rxjava2
compile 'com.squareup.retrofit2:adapter-rxjava2:+'
compile 'io.reactivex.rxjava2:rxjava:+'
compile 'io.reactivex.rxjava2:rxandroid:+'
***baseUrl:****
1. 默认的服务器地址,Retrofit在进行请求一个接口时会根据你填写的
baseurl+方法名 去请求。
****addConverterFactory:****
添加返回数据的解析方式,Retrofit支持多种格式的解析,xml,json,
jackson,Moshi,Protobuf,wire等,添加对这些数据格式的支持同样需要在
Gradle中进行依赖。这些依赖Square公司同样提供了支持。
****CallAdapter:****
Retrofit会将网络请求的接口以回调的方式返回,我们通常会得到一个叫做
Call<类型>的结果,如果我们需要返回其他的结果,例如RxJava形式的结果,需
要对RxJava做支持。如果不需要特殊类型的返回结果,我们是不需要配置的。
****Client:****
通过该方法我们可以添加自己定制的OkHttp
GET注解
1. 用于发送一个get请求
2. GET注解一般必须添加相对路径或绝对路径或者全路径,如果不想在GET注解后添加请求路径,则可以在方法的第一个参数中用@Url注解添加请求路径。
Url注解:
1. 作用于方法参数
2. 用于添加请求的接口地址
3.示例:@GET Calllist(@Url String url);
Path注解:
1. 作用于方法的参数
2. 在URL路径段中 替换指定的参数值。使用String.valueOf()和URL编码
3. 将值转换为字符串。
4. 使值不可为用该注解定义的参数的空
5. 参数值默认使用URL编码
6. 示例://默认使用URL编码 @GET("/user/{name}") Callencoded(@Path("name") String name); //不使用URL编码 @GET("/user/{name}") Call notEncoded(@Path(value="name", encoded=true) String name);
Query注解:
1. 作用于方法的参数
2. 用于添加查询参数,即 请求参数
3. 参数值通过String.valueOf()转换为String并进行URL编码
4. 使用该注解定义的参数,参数值 可以为空,为空时,忽略该值,当传入一个Listarray时,为每个非空item拼接请求键值对,所有的键是统一的,如:name=张三&name=李&name=王五.
5. 示例:@GET("/list") Calllist(@Query("page") int page); @GET("/list") Call list(@Query("category") String category); //传入一个数组 @GET("/list") Call list(@Query("category") String... categories); //不进行URL编码 @GET("/search") Call list(@Query(value="foo", encoded=true) String foo);
QueryMap注解:
1. 作用于方法的参数
2. 以 map的形式添加查询参数,即请求参数
3. 参数的键和值都通过String.valueOf()转换为String格式
4. map的键和值默认进行URL编码
5. map中每一项的 键和值都不能为空,否则抛IllegalArgumentException异常
6. 示例://使用默认URL编码 @GET("/search") Calllist(@QueryMap Map filters); //不使用默认URL编码 @GET("/search") Call list(@QueryMap(encoded=true) Map filters);
POST注解:
1. 用于发送一个POST请求
2. POST注解一般必须添加相对路径或绝对路径或者全路径,如果不想在POST注解后添加请求路径,则可以在方法的第一个参数中用@Url注解添加请求路径
FormUrlEncoded注解:
1. 用于修饰Field注解和FieldMap注解
2. 使用该注解,表示请求正文将使用表单网址编码。字段应该声明为参数,并用@Field注释或FieldMap注释。使用FormUrlEncodied注解的请求将具”applicaton / x-www-form-urlencoded” MIME类型
Field注解
1. 作用于方法的参数
2. 用于发送一个表单请求@FormUrlEncoded @POST("/") Callexample(@Field("name") String name,@Field("occupation") String occupation); //固定或可变数组 @FormUrlEncoded @POST("/list") Call example(@Field("name") String... names);
FieldMap注解:
1. 作用于方法的参数
2. 用于发送一个表单请求
3. map中每一项的键和值都不能为空,否则抛出IllegalArgumentException异常@FormUrlEncoded @POST("/things") Callthings(@FieldMap Map fields);
Header注解:
1. 作用于方法的参数,用于添加请求头
2. 使用该注解定义的请求头可以为空,当为空时,会自动忽略,当传入一个List或array时,为拼接每个非空的item的值到请求头中.具有相同名称的请求头不会相互覆盖,而是会照样添加到请求头中
3. 示例:@GET("/") Callfoo(@Header("Accept-Language") String lang);
HeaderMap注解:
1. 作用于方法的参数,用于添加请求头
2. 以map的方式添加多个请求头,map中的key为请求头的名称,value为请求头的值,且value使用String.valueOf()统一转换为String类型,map中每一项的 键和值都不能为空,否则抛出IllegalArgumentException异常
3. 示例:@GET("/search") void list(@HeaderMap Mapheaders); //map Map headers = new HashMap()<>; headers.put("Accept","text/plain"); headers.put("Accept-Charset", "utf-8");
Headers注解:
1. 作用于方法,用于添加一个或多个请求头
2. 具有相同名称的请求头不会相互覆盖,而是会照样添加到请求头中
3. 示例://添加一个请求头 @Headers("Cache-Control: max-age=640000") @GET("/") ... //添加多个请求头 @Headers({"X-Foo: Bar", "X-Ping: Pong" }) @GET("/") ...
2.1 HTTP注解: (了解)
1. 作用于方法,用于发送一个自定义的HTTP请求
2. 示例://自定义HTTP请求的标准样式 interface Service { @HTTP(method = "CUSTOM", path = "custom/endpoint/") CallcustomEndpoint(); } //发送一个DELETE请求 interface Service { @HTTP(method = "DELETE", path = "remove/", hasBody = true) Call deleteObject(@Body RequestBody object); }
Multipart注解:
1. 作用于方法
2. 使用该注解,表示请求体是多部分的。 每一部分作为一个参数,且用Part注解声明
Part注解:
1. 作用于方法的参数,用于定义Multipart请求的每个part
2. 使用该注解定义的参数,参数值可以为空,为空时,则忽略
3. 使用该注解定义的参数类型有以下3种方式可选:
1, 如果类型是okhttp3.MultipartBody.Part,内容将被直接使用。 省略 part中的名称,即 @Part MultipartBody.Part part
2, 如果类型是RequestBody,那么该值将直接与其内容类型一起使用。 在注释中提供part名称(例如@Part(“foo”)RequestBody foo)。
3, 其他对象类型将通过使用转换器转换为适当的格式。 在注释中提供part名称(例如,@Part(“foo”)Image photo)
4. 示例:@Multipart @POST("/") Callexample( @Part("description") String description, @Part(value = "image", encoding = "8-bit") RequestBody image);
PartMap注解:
1. 作用于方法的参数,以map的方式定义Multipart请求的每个partmap中每一项的键和值都不能为空,否则抛出IllegalArgumentException异常
使用该注解定义的参数类型有以下2种方式可选:
1, 如果类型是RequestBody,那么该值将直接与其内容类型一起使用。
2, 其他对象类型将通过使用转换器转换为适当的格式。
示例:@Multipart @POST("/upload") Callupload( @Part("efile") RequestBody file, @PartMap Map params);
3.2 Streaming注解:
1. 作用于方法
2. 处理返回Response的方法的响应体,即没有将body()转换为byte[]。
1,以上部分注解真正的实现在ParameterHandler类中,,每个注解的真正实现都是ParameterHandler类中的一个final类型的内部类,每个内部类都对各个注解的使用要求做了限制,比如参数是否可空,键和值是否可空等.
2,FormUrlEncoded注解和Multipart注解不能同时使用
3,Path注解与Url注解不能同时使用
4,对于FiledMap,HeaderMap,PartMap,QueryMap这四种作用于方法的注解,其参数类型必须为Map的实例,且key的类型必须为String类型
5,使用Body注解的参数不能使用form 或multi-part编码,即如果为方法使用了FormUrlEncoded或Multipart注解,则方法的参数中不能使用Body注解
6,Retrofit提供了MultiPart注解,说明我们可以上传文件,又提供了Streaming注解,说明我们可以下载文件,我们知道Retrofit可以干这些事,但是我们还是没有办法直接写上传下载代码,这些东西都需要我们自己去封装,这也是为什么目前有很多基于Retrofit构建的二次封装库的原因
https://www.jianshu.com/p/56b5bce47d8c
/**
* 封装Retrofit网络请求框架
* 懒汉式单例模式
*/
public class RetrofitManager {
public static final String BASE_URL = "http://www.zhaoapi.cn/";
private final Retrofit retrofit;
// 静态内部类的单例
private static final class SINGLE_INSTANCE {
private static final RetrofitManager _INSTANCE = new RetrofitManager();
}
public static RetrofitManager getInstance() {
return SINGLE_INSTANCE._INSTANCE;
}
/**
* 在构造方法中构造Retrofit对象
* 设置公共url,解析方式gson,配置OkHttpClient
*/
private RetrofitManager() {
// 构造Retrofit对象
retrofit = new Retrofit.Builder()
// 设置公共的url部分
.baseUrl(BASE_URL)
// 配置解析方式为Gson
.addConverterFactory(GsonConverterFactory.create())
// 配置OKHttpClient
.client(buildOkHttpClient())
.build();
}
@NonNull
private OkHttpClient buildOkHttpClient() {
// 构造OkHttpClient对象
return new OkHttpClient.Builder()
.readTimeout(5, TimeUnit.SECONDS)
.writeTimeout(5, TimeUnit.SECONDS)
.connectTimeout(5, TimeUnit.SECONDS)
.build();
}
/**
* 因为retrofit在create的时候需要传入class
* 并且返回这个类
* @param clazz
* @param
* @return
*/
public T create(Class clazz) {
return retrofit.create(clazz);
}
}
/**
* 点击请求网络登录
* @param view
*/
public void request(View view) {
// 利用Retrofit.create方法构造一个Api接口的实例
ILoginApi iLoginApi = RetrofitManager.getInstance().create(ILoginApi.class);
// 构造一个Call请求,拿到Api接口的实例调用对应的方法去构造一个Call请求
final Call call = iLoginApi.login("login", "18210926066", "123456");
/**
* 异步请求
*/
call.enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
// 通过response.body拿到最后解析后的bean对象
LoginBean loginBean = response.body();
if (loginBean != null && "0".equals(loginBean.getCode())) {
Toast.makeText(MainActivity.this, "请求成功", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onFailure(Call call, Throwable t) {
Toast.makeText(MainActivity.this, "请求失败", Toast.LENGTH_SHORT).show();
}
});
}