Retrofit简介

1.Retrofit干什么的?

Retrofit让你便捷地封装出一个类来给其它地方调用和服务器进行HTTP API调用。

比如,一般来说,不用retrofit的时候,你需要填写http参数,然后get数据下来,然后解析,然后。。。。

用了retrofit之后,你只需a.xxget("参数值")拿到一个对象,就可访问服务器返回的数据了。

retrofit一般都是结合okhttp使用。

2.定义服务接口类

要想做到上面说的“a.xxget”就能简单调用HTTP服务器上的API,需要定义一个interface类,然后使用retrofit对这个类进行实现。

例如下面的interface类:

public interface GitHubService {
  @GET("users/{user}/repos")
  Call<List<Repo>> listRepos(@Path("user") String user);
}

然后通过retrofit提供的功能来配置和实现这个接口:

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.github.com/")
    .build();

GitHubService service = retrofit.create(GitHubService.class);

这样,如果你调用service.listRepos("xiaoli")就等效于访问了“https://api.github.com/users/xiaoli/repos”,并拿到这个地方返回的数据。像下面这样:

Call<List<Repo>> repos = service.listRepos("xiaoli");

3.注解编写

retrofit一大特点就是通过注解来定制调用服务器API时候HTTP请求的一些参数配置。所以需要了解如何retrofit支持的注解。

retrofi一共有5个注解:GET,POST,PUT,DELETE,HEAD。

每个API都要写上相关的注解,说明API是怎么调用的。

例如以下的GET注解,表示“listRepos”函数使用GET的方法访问HTTP的网址:

public interface GitHubService {
  @GET("users/{user}/repos")
  Call<List<Repo>> listRepos(@Path("user") String user);
}

接下来详细介绍一下注解使用规则。

4.URL封装

“@Path”:地址中关联变量

注解中的url地址,可以和变量关联,用大括号(“{ }”)包括,而相应地,在函数参数中用@Path指明变量就可以。

例如下面的变量“id”:

@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId);

“@Query”:关联单个查询参数变量

API中如有“?”后面的那些参数,可以用“@Query”来关联变量。

例如有这样一个API请求URL(两个查询参数:access_token和openid):

https://login.xx.cn/mobile/login?access_token=12345&openid=56789

相应retrofit的规则写法如下:

@GET("/mobile/login")
void getMyMessage(@Query("access_token") String access_token, @Query("openid") String openId);

"@QueryMap" : 关联多个查询参数变量

API中如果有很多查询参数,每个都写一个“@Query”明显太麻烦,所以retrofit又提供了“@QueryMap ”可以一次指定多个参数变量。

例如上面的接口又可以这样写:

@GET("/mobile/login")
void getMyMessage(@QueryMap HashMap<String,String> queryparams);

使用的时候:

HashMap<String,String> params = new HashMap();
params.put("access_token",token);
params.put("openid",openid);

serviceAPI.getMyMessage(params);

注意:“@QueryMap”使用在POST方法,参数会写在url中,服务器编写要注意接收参数而不是body。

5.Header封装

“@Headers”:指定Header域数据

例如:

@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与数据动态关联

可以在接口参数中使用“@Header”动态关联变量,

例如下面的代码,关联了“Authorization”域的值由变量authorization提供:

@GET("user")
Call<User> getUser(@Header("Authorization") String authorization)

注意:如果每个请求都想添加一些特定头域数据,请使用okhttp的拦截器。

okhttp拦截器的例子:

OkHttpClient client = new OkHttpClient();
client.networkInterceptors().add(new Interceptor() {
    @Override
    public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
        com.squareup.okhttp.Response response = chain.proceed(chain.request());

         tokenRequest = response.newBuilder()
                        .header("token", "1234567")
                        .build();
        return chain.proceed(tokenRequest);
    }
});
Retrofit retrofit = new Retrofit.Builder()
        .baseUrl(BASE_URL)
        ...
        .client(client)
        .build();

6.请求数据体封装设置

“@FormUrlEncoded ”: 变量提供表单式数据

会以application/x-www-form-urlencoded类型作为body,参考例子:

@FormUrlEncoded
@POST("user/edit")
Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);

注意使用了“@Field”来定义了key-value的键值对数据。

"@Multipart " : 关联变量实现multipart数据提供

使用“@Part”来关联变量动态对part提供数据。

参考例子:

@Multipart
@PUT("user/photo")
Call<User> updateUser(@Part("photo") RequestBody photo, @Part("description") RequestBody description);


“@Body”: 实现请求的数据体关联变量

参考下面的例子:

@POST("/mobile/login")
void getMyMessage(@Body HashMap<String,String> reqbodydata);

另外一种,使用java类实体变量的例子:

@POST("/mobile/login")
void getMyMessage(@Body User reqbodydata);

7.同步和异步特性

可以通过Call方式实现同步或者异步调用,每个Call实例只能调用一次。需要再调用,则要clone一个新的。

看例子。

定义:

import retrofit.Call;

/* Retrofit 2.0 */
public interface APIService {
    @POST("/list")
    Call<Repo> loadRepo();
}

同步调用:

// Synchronous Call in Retrofit 2.0

Call<Repo> call = service.loadRepo();
Repo repo = call.execute();

异步调用:

// Synchronous Call in Retrofit 2.0
Call<Repo> call = service.loadRepo();
call.enqueue(new Callback<Repo>() {
    @Override
    public void onResponse(Response<Repo> response) {
        // Get result Repo from response.body()
    }

    @Override
    public void onFailure(Throwable t) {
    }
});
注意,Callback被调用的时候,如果是android平台,是在主线程,而如果是“JVM”中,则和HTTP请求同一个线程。

可以取消正在进行的请求:call.cancel() 。

8.结束

retrofit是个方便我们调用服务器API的一个工具,如果很多API接口,可以考虑使用,如果只是一两个,没必要搞那么复杂。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值