Retrofit的基本用法

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结合更是堪称完美。

,