之前做项目一直用的都是okHttp3.0的网络请求框架,身为程序猿怎么能不对新出的东西学习一番呢,说是新出其实也很久了。今天周六公司没事,学习记录一下Retrofit2.0(https://github.com/square/retrofit)的使用方法,如有错误请不吝指教。
Retrofit的优点:
- 可以配置不同HTTP client来实现网络请求,如okhttp、httpclient等
- 请求的方法参数注解都可以定制
- 支持同步、异步和RxJava
- 超级解耦
- 可以配置不同的反序列化工具来解析数据,如json、xml等
- 使用非常方便灵活
- 框架使用了很多设计模式(感兴趣的可以看看源码学习学习)
说了优点当然也是有缺点的:
- 不能接触序列化实体和响应数据
- 执行的机制太严格
- 使用转换器比较低效
- 只能支持简单自定义参数类型
废话不多说直接记录一下我的使用流程:
//retrofit的依赖
compile 'com.squareup.retrofit2:retrofit:2.1.0'
//底层基于okhttp的
compile 'com.squareup.okhttp3:okhttp:3.3.1'
//将请求结果直接转换成JavaBean需要用到,如果不需要可忽略
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
定义接口:
public interface NewsApi {
//接口
@GET("toutiao/index?key=a2924a746f129e1f4b37d81dc5fea156")
Call<NewsBean> getDataFromNet(@Query("type") String type);
}
使用retrofit:
构建retrofit对象:
Retrofit retrofit = new Retrofit.Builder()
//配置BaseUrl
.baseUrl("http://v.juhe.cn/")
.addConverterFactory(GsonConverterFactory.create())
.build();
创建接口对象:
NewsApi newsApi = retrofit.create(NewsApi.class);
使用接口对象调用我们定义在接口中的方法并获得Call对象,NewsBean是我们自己定义的那个JavaBean:
Call<NewsBean> call = newsApi.getDataFromNet(parameter);
执行请求并直接解析出数据了,不再用Gson和JsonObject来自己解析了:
call.enqueue(new Callback<NewsBean>() {
@Override
public void onResponse(Call<NewsBean> call, Response<NewsBean> response) {
List<DataBean> data = response.body().result.data;
String thumbnail_pic_s = data.get(0).thumbnail_pic_s;
LogUtils.LogUtil("获取到的数据=" + thumbnail_pic_s);
}
@Override
public void onFailure(Call<NewsBean> call, Throwable t) {
}
});
特殊情况1,接口里面只有参数值没有参数名称的使用方法,这里使用了2个参数的接口,并且没有定义返回数据的JavaBean:
定义接口:
public interface TestApi {
@GET("api/data/Android/{p}/{page}")
Call<ResponseBody> getAndroidInfo(@Path("page") int page, @Path("p") int p);
}
使用方法,和之前的一样,只是返回的数据不再是已经定义的JavaBean,这里就需要自己使用Gson或者JsonObject来解析了。
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://gank.io/")
.build();
TestApi testApi = retrofit.create(TestApi.class);
Call<ResponseBody> androidInfo = testApi.getAndroidInfo(1,10);
androidInfo.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
try {
String json = response.body().string();
LogUtils.LogUtil(json);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
特殊情况2,接口里面含有多个参数:
还是只需要改变一下接口就行了:
public interface NewsApi {
//接口
@GET("toutiao/index?")
Call<NewsBean> getDataFromNet(@QueryMap Map<String,String> params);
}
在使用时传入参数需要先构造一个Map集合,存入参数,键就是参数名,值就是参数的值,其它完全都一样,不再赘述。
//参数集合
HashMap<String, String> params = new HashMap<>();
params.put("type","top");
params.put("key","a2924a746f129e1f4b37d81dc5fea156");
Call<NewsBean> call = newsApi.getDataFromNet(params);