简介

Retrofit 是一个Square开发的类型安全的REST安卓客户端请求库,这个库为网络认证、API请求以及用OkHttp发送网络请求提供了强大的框架。因为其简单与出色的性能,Retrofit是安卓上最流行的HTTP Client库之一。

来自Retrofit官网的介绍:

Type-safe HTTP client for Android and Java by Square, Inc.

原理

在发起请求时,整个框架主要通过Call来封装每一次的请求。每一次的同步或者异步请求都会有Dispatcher的参与,不同的是:

同步

Dispatcher会在同步执行任务队列中记录当前被执行过得任务Call,同时在当前线程中去执行Call的getResponseWithInterceptorChain()方法,直接获取当前的返回数据Response;

异步

首先来说一下Dispatcher,Dispatcher内部实现了懒加载无边界限制的线程池方式,同时该线程池采用了 SynchronousQueue这种阻塞队列。SynchronousQueue每个插入操作必须等待另一个线程的移除操作,同样任何一个移除操作都等待另一个线程的插入操作。显然这是一种快速传递元素的方式,也就是说在这种情况下元素总是以最快的方式从插入者(生产者)传递给移除者(消费者),这在多任务队列中是最快处理任务的方式。

Retrofit用法

1创建实体类

首先需要创建一个POJO(Java对象)。服务器返回的JSON数据不能在Java里直接使用,所以我们需要用模型类来做转换。这里使用jsonschema2pojo来创建POJO。

jsonschema2pojo网址:http://www.jsonschema2pojo.org/

将json数据复制到jsonschema2pojo

android Hotspot开启 android rest_Android



android Hotspot开启 android rest_网络请求_02



复制JSON字符串到输入框中,填写报名、类名,源代码类型选择JSON,注解类型选择Gson,点击Preview即可得到对应的POJO,如下图


android Hotspot开启 android rest_Retrofit_03


import com.google.gson.annotations.SerializedName;

@Generated("org.jsonschema2pojo")

可删除

2导入所需要用到的包

retrofit-2.0.0-beta2.jar                     àRetrofit库

converter-gson-2.0.0-beta2_.jar    àGson解析库

gson-2.4.jar                                      àGson解析库

okhttp-2.5.0.jar                                 àOkhttp请求库

okio-1.6.0.jar                                    àOkhttp请求库

httpmime-4.5                                    à加快网络访问库

okhttp-urlconnection-2.5.0              à加快网络访问库

由于Retrofit依赖于okhttp,所以需要集成okhttp,API返回的数据为JSON格式,在此我使用的是Gson对返回数据解析。

1)OkHttp:

OkHttp是一个高效的HTTP库:

1)支持 SPDY,共享同一个Socket来处理同一个服务器的所有请求

2)如果SPDY不可用,则通过连接池来减少请求延时

3)无缝的支持GZIP来减少数据流量

4)缓存响应数据来减少重复的网络请求

2)GSON:

Gson 是 Google提供的用来在 Java对象和 JSON数据之间进行映射的 Java类库。可以将一个 JSON字符串转成一个 Java对象,或者反过来。


3声明接口

/**
 *Call<T> get();必须是这种形式,这是2.0之后的新形式
 * 如果不需要转换成Json数据,可以用了ResponseBody;
 * 你也可以使用Call<GsonBean>get();这样的话,需要添加Gson转换器
 */
public interface ApiStores {
@GET("adat/sk/{cityId}.html")
   Call<ResponseBody> getWeather(@Path("cityId") StringcityId);
}



如果链接是http://ip.taobao.com/service/getIpInfo.php?ip=202.202.33.33

@GET("http://ip.taobao.com/service/getIpInfo.php")
 Call<ResponseBody>getWeather(@Query("ip") String ip);



例: GET请求

public interface DTNewsService {
       @GET("***?filter[limit]=10&filter[order]=date%20DESC&filter[where][date][lt]=2015-11-11")
       Call<List<DTNewsBean>>  getTownNews();
}



public interface DTNewsService {
@GET("News")
       Call<List<DTNewsBean>>  getTownNews(
                     @Query("filter[limit]")String limit,
                     @Query("filter[order]")String order,
                     @Query("filter[where][date][lt]")String date);
       Call<List<DTNewsBean>>  getTownNews();
}



例:登录请求1

网址不要以/开头

public interface DTPersonService {
       @POST("User/login")
       Call<DTPerson>login(@Body DTPerson person);
}



DTPerson为用户信息对象,其中包括用户名,密码以及登录后得到的所有结果

如果要提交多个DTPerson对象可以将body中哦DTPerson改为:List<DTPerson>

例: POST登录请求1


@FormUrlEncoded
	@POST("Accounts/login")
	Call<AccountLogin> login(@Field("username") String username, @Field("password") String password);



其中的参数为账号和密码

4接口调用

创建一个Retrofit 对象

Retrofit retrofit = new Retrofit.Builder()
               //这里建议:- Base URL: 总是以/结尾;- @Url: 不要以/开头
              .baseUrl("http://www.weather.com.cn/")
              .build();



再用这个Retrofit对象创建一个ApiStores对象

ApiStores apiStores =retrofit.create(ApiStores.class);
Call<ResponseBody> call =apiStores.getWeather("101010100");



例:

BASE_URL:建议以/结尾

private static String BASE_URL ="http://202.107.149.202:3001/api/v1/";
Retrofit retrofit = new Retrofit.Builder()
              .addConverterFactory(GsonConverterFactory.create())
              .baseUrl(BASE_URL)
              .build();
              DTNewsService api = retrofit.create(DTNewsService.class);
              Call<List<DTNewsBean>>call = api.getTownNews();
//Call<List<DTNewsBean>> call =service.getTownNews("10", "dateDESC","2015-11-11");



例:登录:

DTPersonService service2 =retrofit.create(DTPersonService.class);
Call<DTPerson> call2 = service2.login(newDTPerson("15859327863", "zhouyouxi"));



5同步调用

同步调用

ResponseBody = call.execute();

6异步调用

call.enqueue(new Callback<ResponseBody>(){
           @Override
           public void onResponse(Response<ResponseBody> response) {
               //成功返回数据后在这里处理
            }
            @Override
            public voidonFailure(Throwable t) {
               //请求失败在这里处理
           }
       });

7移除请求

call.cancel();