1. Retrofit 简介
1.1 定义
Retrofit 是底层使用 OKHttp 封装的一个网络加载框架。它的网络请求的工作本质上是由 OkHttp 完成,而 Retrofit 仅负责网络请求接口的封装。
1.2 使用条件
Retrofit 至少需要 Java 7 或 Android 2.3
1.3 Retrofit 特点
- 使用注解以简化代码量
- Retrofit 将你的 HTTP API 转换为 Java 接口类(比如 GithubService)
- 通过这个接口类(GithubService)创建的每个 call 都可以向远程 Web 服务器发出同步或异步 HTTP 请求
1.4 Retrofit 资料
github地址:https://github.com/square/retrofit
github官方文档:http://square.github.io/retrofit/
2. Retrofit 请求说明
2.1 请求方法
每个方法都必须具有请求方法和相对 URL 的 HTTP 注释。有五个内置注释:GET,POST,PUT,DELETE 和 HEAD。资源的相对 URL 在注释中指定。如下两个示例:
@GET("users/list")
@GET("users/list?sort=desc") //可以在 URL 中指定查询参数
2.2 URL 操作
可以使用方法上的替换块和参数动态地更新请求URL。 替换块是由{and}包围的字母数字字符串。
@Path 表示用后面传入的值替换请求 URL 中的参数。示例如下:
@GET("group/{id}/users") //用 groupId 替换掉上面链接 URL 中的 {id} Call<List<User>> groupList(@Path("id") int groupId);
@Query 表示在 URL 后面追加查询条件。示例如下:
@GET("group/{id}/users") //在链接 URL 后面追加 ?sort= Call<List<User>> groupList(@Path("id") int groupId, @Query("sort") String sort);
@QueryMap 表示在 URL 后面追加多个查询条件,这些条件用 Map 对象封装起来。示例如下:
@GET("group/{id}/users") //在链接 URL 后面追加 ?options= Call<List<User>> groupList(@Path("id") int groupId, @QueryMap Map<String, String> options);
2.3 请求体(REQUEST BODY)
@Body 注释可以将一个对象指定为 HTTP 请求体类型。示例如下:
@POST("users/new") //将 User 对象指定为 HTTP 请求体类型 Call<User> createUser(@Body User user);
2.4 格式编码及多部件(FORM ENCODED AND MULTIPART)
@FormUrlEncoded 使用这个注释,说明要发送表单编码数据。因此每个键值都需要使用 @Field 进行注释,其中包含名称和提供该值的对象。示例如下:
@FormUrlEncoded @POST("user/edit") //这里表示表单的两列,first_name 和 last_name Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);
@Multipart 这个注释表示使用多部件请求。每一个部件使用 @part 注释声明。示例如下:
@Multipart @PUT("user/photo") Call<User> updateUser(@Part("photo") RequestBody photo, @Part("description") RequestBody description);
2.5 HEADER 操作
Headers 你可以为一个方法设置静态 headers,示例如下:
//示例一 @Headers("Cache-Control: max-age=640000") @GET("widget/list") Call<List<Widget>> widgetList(); //示例二 @Headers({ "Accept: application/vnd.github.v3.full+json", "User-Agent: Retrofit-Sample-App" }) @GET("users/{username}") Call<User> getUser(@Path("username") String username);
因为标题之间不会互相覆盖,所以所有相同的标题都会包含在请求中。
@Header 使用这个注释可以动态更新请求头。在使用这个注释的时候,必须要提供相应的参数,如果参数值为空,则头被省略;否则,将使用 toString 处理后的结果作为参数。示例如下:
@GET("user") Call<User> getUser(@Header("Authorization") String authorization)
2.6 同步和异步说明
Call 对象可以同步或者异步执行,每个对象只能被调用一次。当然,你可以调用 clone() 方法创建一个新的对象。在 Android 中,回调方法将在主线程中执行。
2.7 转换工具
Gson: com.squareup.retrofit2:converter-gson
Jackson: com.squareup.retrofit2:converter-jackson
Moshi: com.squareup.retrofit2:converter-moshi
Protobuf: com.squareup.retrofit2:converter-protobuf
Wire: com.squareup.retrofit2:converter-wire
Simple XML: com.squareup.retrofit2:converter-simplexml
Scalars (primitives, boxed, and String): com.squareup.retrofit2:converter-scalars
以上是 Retrofit 提供的一些对象转换工具,Gson 转换代码示例如下:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com")
.addConverterFactory(GsonConverterFactory.create())
.build();
GitHubService service = retrofit.create(GitHubService.class);
3. Retrofit 使用实践
3.1 添加依赖
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0' // 用Gson解析json的转换器
3.2 添加权限
<uses-permission android:name="android.permission.INTERNET"/>
3.3 写 URL 接口类
备注:
1. demo 请求 URL:http://gank.io/api/data/福利/count/page
2. PhotoBean 为请求结果 DataBean 对象
GetRequest_Interface.java
package com.demo.thorn.retrofitdemo; import retrofit2.Call; import retrofit2.http.GET; import retrofit2.http.Path; public interface GetRequest_Interface { // 注解里传入 网络请求 的部分URL地址 // getCall()是接受网络请求数据的方法 @GET("/api/data/福利/{count}/{page}") Call<PhotoBean> getCall(@Path("count") int count,@Path("page") int page); }
3.4 程序中调用
MainActivity.java
package com.demo.thorn.retrofitdemo; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; public class MainActivity extends AppCompatActivity { public static final String BASE_GALLERY_URL = "http://gank.io"; private int mCount = 10; private int mPage = 1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //步骤一:创建Retrofit对象 Retrofit retrofit = new Retrofit.Builder() .addConverterFactory(GsonConverterFactory.create()) .baseUrl(BASE_GALLERY_URL) .build(); // 步骤二:创建网络请求接口的实例 GetRequest_Interface request = retrofit.create(GetRequest_Interface.class); //步骤三:对发送的请求进行封装 Call<PhotoBean> call = request.getCall(mCount,mPage); //步骤四:发送网络请求(异步) call.enqueue(new Callback<PhotoBean>() { @Override public void onResponse(Call<PhotoBean> call, Response<PhotoBean> response) { Log.i("jin",response.message().toString()); Log.i("jin",response.body().getResults().get(1).getUrl()); } @Override public void onFailure(Call<PhotoBean> call, Throwable t) { } }); } }
4. Retrofit 注解类型(补充)
4.1 网络请求方法类注解
- @GET
- @POST
- @PUT
- @DELETE
- @PATH
- @HEAD
- @OPTIONS
- @HTTP
4.2 标记类注解
- FormUrlEncoded
- Multipart
- Streaming
4.3 网络请求参数
- @Header
- @headers
- @URL
- @Body
- @Path
- @Field
- @FieldMap
- @Part
- @PartMap
- @Query
- @QueryMap