android Retrofit 2.0
一、介绍
主流网络请求库
Android-Async-Http:https://github.com/loopj/android-async-http
Volley :https://github.com/stormzhang/AndroidVolley
OkHttp:https://github.com/square/okhttp
Retrofit:https://github.com/square/retrofit
比较:
二、GET方式请求网络
1、导如到项目
implementation 'com.squareup.okhttp3:okhttp:3.10.0' implementation 'com.squareup.retrofit2:retrofit:2.0.2' implementation 'com.squareup.retrofit2:converter-gson:2.0.2'
2、添加网络访问权限
3、自定义用来接收服务器返回数据的Bean
package com.lht.liuhaitao;public class UserBean { private String status; private Content content; private static class Content{ private int id; private String name; private int age; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Content{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + '}'; } } public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } public Content getContent() { return content; } public void setContent(Content content) { this.content = content; } @Override public String toString() { return "UserBean{" + "status='" + status + '\'' + ", content=" + content + '}'; }}
4、定义接口
package com.lht.liuhaitao;import retrofit2.Call;import retrofit2.http.GET;public interface IGetRequest { @GET("/test.php?id=1") Call getCall(); // 注解里传入 网络请求 的部分URL地址 // Retrofit把网络请求的URL分成了两部分:一部分放在Retrofit对象里,另一部分放在网络请求接口里 // 如果接口里的url是一个完整的网址,那么放在Retrofit对象里的URL可以忽略 // getCall()是接受网络请求数据的方法}
5、处理返回数据
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); but=findViewById(R.id.but_ok); imageView=findViewById(R.id.pothoImg); but.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { request(); } }); } private void request(){ Retrofit retrofit=new Retrofit.Builder() .baseUrl("http://xxx.xxx.xxx.xxx/")//// 设置 网络请求 Url .addConverterFactory(GsonConverterFactory.create())//设置使用Gson解析(记得加入依赖) .build(); //创建 网络请求接口 的实例 IGetRequest request=retrofit.create(IGetRequest.class); // //对 发送请求 进行封装 Call call=request.getCall(); //发送网络请求(异步) call.enqueue(new Callback() { @Override public void onResponse(Call call, Response response) { UserBean userBean=response.body(); Log.e(TAG, "onResponse: "+userBean); } @Override public void onFailure(Call call, Throwable t) { Log.e(TAG, "onFailure: "+t.getMessage() ); } }); }
三、POST方式网络请求
1、定义接口
public interface IPostRequest { @POST("test.php") @FormUrlEncoded Call getCall(@Field("id") String targetSentence); //采用@Post表示Post方法进行请求(传入部分url地址) // 采用@FormUrlEncoded注解的原因:API规定采用请求格式x-www-form-urlencoded,即表单形式 // 需要配合@Field 向服务器提交需要的字段,服务器端用POST可以接收id的值}
2、定义bean
package com.lht.liuhaitao;public class UserBean { private String status; private Content content; private static class Content{ private int id; private String name; private int age; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Content{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + '}'; } } public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } public Content getContent() { return content; } public void setContent(Content content) { this.content = content; } @Override public String toString() { return "UserBean{" + "status='" + status + '\'' + ", content=" + content + '}'; }}
3、
private void request(){ Retrofit retrofit=new Retrofit.Builder() .baseUrl("http://xxx.xxx.xxx.xxx/")//// 设置 网络请求 Url .addConverterFactory(GsonConverterFactory.create())//设置使用Gson解析(记得加入依赖) .build(); //创建 网络请求接口 的实例 IPostRequest request=retrofit.create(IPostRequest.class); // //对 发送请求 进行封装 Call call=request.getCall("hello"); //发送网络请求(异步) call.enqueue(new Callback() { @Override public void onResponse(Call call, Response response) { UserBean userBean=response.body(); Log.e(TAG, "onResponse: "+userBean); } @Override public void onFailure(Call call, Throwable t) { Log.e(TAG, "onFailure: "+t.getMessage() ); } }); }
三、常用得到参数
1、注解类型
2、注解说明
(1)第一类:网络请求方法
详细说明:
a. @GET、@POST、@PUT、@DELETE、@HEAD
以上方法分别对应 HTTP中的网络请求方式
网络请求的完整 Url =在创建Retrofit实例时通过.baseUrl()设置 +网络请求接口的注解设置(下面称 “path“ )
建议采用第三种方式来配置,并尽量使用同一种路径形式。
@HTTP
- 作用:替换@GET、@POST、@PUT、@DELETE、@HEAD注解的作用 及 更多功能拓展
- 具体使用:通过属性method、path、hasBody进行设置
public interface GetRequest_Interface { /** * method:网络请求的方法(区分大小写) * path:网络请求地址路径 * hasBody:是否有请求体 */ @HTTP(method = "GET", path = "blog/{id}", hasBody = false) Call getCall(@Path("id") int id); // {id} 表示是一个变量 // method 的值 retrofit 不会做处理,所以要自行保证准确}
3、标记
@FormUrlEncoded:
- 作用:表示发送form-encoded的数据
每个键值对需要用@Filed来注解键名,随后的对象需要提供值。
b. @Multipart
- 作用:表示发送form-encoded的数据(适用于 有文件 上传的场景)
每个键值对需要用@Part来注解键名,随后的对象需要提供值。
具体使用如下:
GetRequest_Interface
public interface GetRequest_Interface { /** *表明是一个表单格式的请求(Content-Type:application/x-www-form-urlencoded) * Field("username")
表示将后面的 String name
中name的取值作为 username 的值 */ @POST("/form") @FormUrlEncoded Call testFormUrlEncoded1(@Field("username") String name, @Field("age") int age); /** * {@link Part} 后面支持三种类型,{@link RequestBody}、{@link okhttp3.MultipartBody.Part} 、任意类型 * 除 {@link okhttp3.MultipartBody.Part} 以外,其它类型都必须带上表单字段({@link okhttp3.MultipartBody.Part} 中已经包含了表单字段的信息), */ @POST("/form") @Multipart Call testFileUpload1(@Part("name") RequestBody name, @Part("age") RequestBody age, @Part MultipartBody.Part file);}// 具体使用 GetRequest_Interface service = retrofit.create(GetRequest_Interface.class); // @FormUrlEncoded Call call1 = service.testFormUrlEncoded1("Carson", 24); // @Multipart RequestBody name = RequestBody.create(textType, "Carson"); RequestBody age = RequestBody.create(textType, "24"); MultipartBody.Part filePart = MultipartBody.Part.createFormData("file", "test.txt", file); Call call3 = service.testFileUpload1(name, age, filePart);
4、网络请求参数
a. @Header & @Headers
- 作用:添加请求头 &添加不固定的请求头
-
// @Header@GET("user")Call
getUser(@Header("Authorization") String authorization)// @Headers@Headers("Authorization: authorization")@GET("user")Call getUser()// 以上的效果是一致的。// 区别在于使用场景和使用方式// 1. 使用场景:@Header用于添加不固定的请求头,@Headers用于添加固定的请求头// 2. 使用方式:@Header作用于方法的参数;@Headers作用于方法 b. @Body
- 作用:以
Post
方式 传递 自定义数据类型 给服务器 - 特别注意:如果提交的是一个Map,那么作用相当于
@Field
不过Map要经过
FormBody.Builder
类处理成为符合 Okhttp 格式的表单,如:
FormBody.Builder builder = new FormBody.Builder();builder.add("key","value");
c. @Field & @FieldMap
- 作用:发送 Post请求 时提交请求的表单字段
- 具体使用:与
@FormUrlEncoded
注解配合使用
public interface GetRequest_Interface { /** *表明是一个表单格式的请求(Content-Type:application/x-www-form-urlencoded) * Field("username")
表示将后面的 String name
中name的取值作为 username 的值 */ @POST("/form") @FormUrlEncoded Call testFormUrlEncoded1(@Field("username") String name, @Field("age") int age);/** * Map的key作为表单的键 */ @POST("/form") @FormUrlEncoded Call testFormUrlEncoded2(@FieldMap Map map);}// 具体使用 // @Field Call call1 = service.testFormUrlEncoded1("Carson", 24); // @FieldMap // 实现的效果与上面相同,但要传入Map Map map = new HashMap<>(); map.put("username", "Carson"); map.put("age", 24); Call call2 = service.testFormUrlEncoded2(map);
d. @Part & @PartMap
-
作用:发送 Post请求 时提交请求的表单字段
与@Field的区别:功能相同,但携带的参数类型更加丰富,包括数据流,所以适用于 有文件上传 的场景
-
具体使用:与
@Multipart
注解配合使用
public interface GetRequest_Interface { /** * {@link Part} 后面支持三种类型,{@link RequestBody}、{@link okhttp3.MultipartBody.Part} 、任意类型 * 除 {@link okhttp3.MultipartBody.Part} 以外,其它类型都必须带上表单字段({@link okhttp3.MultipartBody.Part} 中已经包含了表单字段的信息), */ @POST("/form") @Multipart Call testFileUpload1(@Part("name") RequestBody name, @Part("age") RequestBody age, @Part MultipartBody.Part file); /** * PartMap 注解支持一个Map作为参数,支持 {@link RequestBody } 类型, * 如果有其它的类型,会被{@link retrofit2.Converter}转换,如后面会介绍的 使用{@link com.google.gson.Gson} 的 {@link retrofit2.converter.gson.GsonRequestBodyConverter} * 所以{@link MultipartBody.Part} 就不适用了,所以文件只能用 @Part MultipartBody.Part */ @POST("/form") @Multipart Call testFileUpload2(@PartMap Map args, @Part MultipartBody.Part file); @POST("/form") @Multipart Call testFileUpload3(@PartMap Map args);}// 具体使用 MediaType textType = MediaType.parse("text/plain"); RequestBody name = RequestBody.create(textType, "Carson"); RequestBody age = RequestBody.create(textType, "24"); RequestBody file = RequestBody.create(MediaType.parse("application/octet-stream"), "这里是模拟文件的内容"); // @Part MultipartBody.Part filePart = MultipartBody.Part.createFormData("file", "test.txt", file); Call call3 = service.testFileUpload1(name, age, filePart); ResponseBodyPrinter.printResponseBody(call3); // @PartMap // 实现和上面同样的效果 Map fileUpload2Args = new HashMap<>(); fileUpload2Args.put("name", name); fileUpload2Args.put("age", age); //这里并不会被当成文件,因为没有文件名(包含在Content-Disposition请求头中),但上面的 filePart 有 //fileUpload2Args.put("file", file); Call call4 = service.testFileUpload2(fileUpload2Args, filePart); //单独处理文件 ResponseBodyPrinter.printResponseBody(call4);}
e. @Query和@QueryMap
-
作用:用于
@GET
方法的查询参数(Query = Url 中 ‘?’ 后面的 key-value)如:url = http://www.println.net/?cate=android,其中,Query = cate
-
具体使用:配置时只需要在接口方法中增加一个参数即可:
@GET("/") Call cate(@Query("cate") String cate);}// 其使用方式同 @Field与@FieldMap,这里不作过多描述
f. @Path
- 作用:URL地址的缺省值
- 具体使用:
public interface GetRequest_Interface { @GET("users/{user}/repos") Call getBlog(@Path("user") String user ); // 访问的API是:https://api.github.com/users/{user}/repos // 在发起请求时, {user} 会被替换为方法的第一个参数 user(被@Path注解作用) }
g. @Url
- 作用:直接传入一个请求的 URL变量 用于URL设置
- 具体使用:
public interface GetRequest_Interface { @GET Call testUrlAndQuery(@Url String url, @Query("showAll") boolean showAll); // 当有URL注解时,@GET传入的URL就可以省略 // 当GET、POST...HTTP等方法中没有设置Url时,则必须使用 {@link Url}提供}
汇总
四、 Retrofit 的拓展使用
Retrofit的使用场景非常丰富,如支持RxJava和Prototocobuff
具体设置也非常简单 & 方便:
<-- 主要在创建Retrofit对象中设置 -->
Retrofit retrofit = new Retrofit.Builder() .baseUrl(""http://fanyi.youdao.com/"") .addConverterFactory(ProtoConverterFactory.create()) // 支持Prototocobuff解析 .addConverterFactory(GsonConverterFactory.create()) // 支持Gson解析 .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) // 支持RxJava .build();
很棒 https://blog.csdn.net/carson_ho/article/details/73732076
更多相关文章
- 箭头函数的基础使用
- NPM 和webpack 的基础使用
- Python list sort方法的具体使用
- 【阿里云镜像】使用阿里巴巴DNS镜像源——DNS配置教程
- android 使用html5作布局文件: webview跟javascript交互
- Android(安卓)Resource介绍和使用
- "Failed to fetch URL https://dl-ssl.google.com/android/repos
- 使用NetBeans搭建Android开发环境
- android 零星调试笔记