Retrofit是Square出品的一个针对Android开发的网络框架,其本身其实是对OKHttp的二次封装,旨在简化网络请求,让用户在不需要了解OKHttp的情况下就能使用。
关于OKHttp,可在一下网站中查看其用法:
http://square.github.io/okhttp/
当然,Square对Retrofit也做了简单介绍,网址如下:
http://square.github.io/retrofit/
下面我们学习一下Retrofit的基本用法:
在项目中引入Retrofit:
moven形式:
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>retrofit</artifactId>
<version>2.1.0</version>
</dependency>
gradle形式:
compile 'com.squareup.retrofit2:retrofit:2.1.0'
Retrofit是基于接口进行网络请求的,所以在定义请求接口时,要以接口的形式进行定义:
public interface GitHubService {
@GET("users/{user}/repos")
Call<List<Repo>> listRepos(@Path("user") String user);
}
这是一个请求接口定义的基本形式,当然,也可以将多个请求接口都定义在GitHubService中。在理解这种标注形式之前,我们有必要对URL的构成做个简单了解。
URL的基本构成:domain + path + param
如:http://www.baidu.com/search?q=Android
解析:
domain:http://www.baidu.com/
path: search/
param: q=Android
Retrofit请求接口标注说明:
Retrofit对请求接口的定义采用了标注的形式,使开发者可以快速地对请求方式,URL的路径和请求参数进行定义。下面对几种常用的标注方式进行简单的了解。
请求方式标注:
Retrofit提供了常用的GET,POST, PUT, DELTE等请求方式,其注解方式是在大写的请求方式名前加@符号。如:
GET ==> @GET
POST ==> @POST
路径标注:
path部分以()括起来,并跟在请求方式标注后,如果path中是变量,应该用{}扩起来,然后在参数中使用@Path标明参数是路径的一部分,如上面示例所示,listRepos接口中的user参数就是Path的一部分:
listRepos(“Freeman”) // 生成的path部分:users/Freeman/repos
请求参数标注
如果请求接口中的参数表示请求参数,应使用@Query标注表明:
public interface GitHubService {
@GET("search")
Call<List<Result>> search(@Query("q") String key, @Query("pager") int pager);
}
PS:路径后面不需要?对于第一个参数,Retrofit2.0会自动使用?将path和param部分分隔的。
search("Android", 1); // 生成的path+param部分:search?q=key&pager=1;
如果有多个请求参数,可使用Map结构,如下所示:
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @QueryMap Map<String, String> options);
POST方式请求
因为POST请求时,参数不会拼接在URL尾部,所以使用@Body进行标注:
@POST("users/new")
Call<User> createUser(@Body User user);
Form表单提交时,字段使用@Field进行标注,同时,需要在请求接口前面标注为@FormUrlEncoded,表明是表单提交形式:
@FormUrlEncoded
@POST("user/edit")
Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);
Multipart形式提交时,使用@Part对各部分进行标注,同时使用@Multipart在请求方式前表明为多媒体提交方式:
@Multipart
@PUT("user/photo")
Call<User> updateUser(@Part("photo") RequestBody photo, @Part("description") RequestBody description);
Http首部标注
对于某些接口,也许我们需要特殊的Http首都字段,这事后就可以对Http首部进行自定义,Retrofit提供的这种方式可谓很人性化。Retrofit使用@Header(“key:value”)的形式对Http首部进行标注:
@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);
@GET("user")
Call<User> getUser(@Header("Authorization") String authorization);
Retrofit请求过程
Retrofit调用接口的方式很简单,只需要简单的几行就可完成Http的请求工作:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.build();
GitHubService service = retrofit.create(GitHubService.class);
service.listRepos("Freeman");
这样就完成了Http的请求过程,其中的baseUrl就是URL中的domain部分,Retrofit在调用接口时会将domain和标注的path,param等进行拼接。然后通过返回的Retrofit的远程对象(Call)完成Http的请求过程。
// 通过repos接收网络数据
Call<List<Repo>> repos = service.listRepos("octocat");
// 同步请求方式(注意:同步方式会阻塞主线程,而Android不允许在主线程中进行网络请求,所以在使用同步方式时需要在子线程中进行操作)
try {
Response<T> queryResult = call.execute();
if (queryResult != null) {
// 获取请求数据后进行的操作
}
} catch (Exception e) {
e.printStackTrace(System.out);
}
// 异步请求方式
call.enqueue(new Callback<DesignerListBean>() {
@Override
public void onResponse(Call<DesignerListBean> call, Response<DesignerListBean> response) {
if (response.isSuccessful()) {
// 数据请求成功时的操作
} else {
// 数据请求失败时的操作
}
}
@Override
public void onFailure(Call<DesignerListBean> call, Throwable t) {
// 网络出现问题时被调用
}
});
总结
至此,Retrofit的基本用法就告一段落。就目前来说,Retrofit封装的还是很强大,简化了整个网络请求的流程,同时还提供了多种数据解析方式,如Gson, ProtocolBuf等。而与RxJava结合更是堪称完美。