简介
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中
复制JSON字符串到输入框中,填写报名、类名,源代码类型选择JSON,注解类型选择Gson,点击Preview即可得到对应的POJO,如下图
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();