Retrofit实现网络请求
技术概述
团队项目中前端需要获取后端的数据,android开发中网络请求比较频繁,可以使用Retrofit框架来简化网络请求操作,因为其网络请求的工作本质是OktHttp完成的,而Retrofit仅需负责网络请求接口的封装,可以使编程简单化。
难点:对有些注释不够了解会在使用的时候出现乱用的情况另外由于在实战中使用的是异步的请求,所以会遇到数据回调填充的问题。
技术详述
因为Retrofit主要起到的是一个网络请求接口封装的作用,具体请求操作都由OkHttp来实现,所以最初的配置会比较简单,只需插入相关依赖即可完成。
- 添加依赖
dependencies {
compile 'com.squareup.retrofit2:retrofit:2.0.2'
// Retrofit库
compile 'com.squareup.okhttp3:okhttp:3.1.2'
// Okhttp库
}
随后就是数据类以及描述网络请求的接口的创建,Retrofit将Http请求抽象成java接口,采用注解描述网络请求参数和配置网络请求参数。
- 添加数据接收类,只需实现get与set方法以及所需的相关构造函数即可
public class Occasion{
private int occasionId;
private String occasionName;
public Occasion(int occasionId,String occasionName){
this.occasionId=occasionId;
this.occasionName=occasionName;
}
public int getOccasionId(){
return occasionId;
}
public void setOccasionId(int occasionId){
this.occasionId=occasionId;
}
public String getOccasionName(){
return occasionName;
}
public void setOccasionName(String occasionName){
this.occasionName=occasionName;
}
}
- 添加网络请求接口,如上所述的采用注解进行描述,下面是一些用到这个数据类的接口
当然Retrofit需要把构建的网络请求接口通过Retrofit对象进行创建,Retrofit对象需要设置一些必要的数据,比如说我们团队项目需要接收json数据就得给他配置相关的数据解析器,同时由于后续的请求操作都是由OkHttp具体实现,所以需要绑定一个OkHttpClinent对象
- 构建Retrofit对象
最后就需要发送网络请求并对返回的数据进行处理,首先就是调用构建的Retrofit对象创建所要用到的网络请求接口并对发送请求进行封装,而后我们这次采用的是异步请求的操作,并且把相关的操作都封装到一个类的方法里可以实现复用
- 对发送请求进行封装
final PostInterfaces request=retrofit.create(PostInterfaces.class);
Call<ResponseModel<Blog[]>> call=request.getBlog(token,getBlogRequest);
- 异步发送网络请求
call.enqueue(new Callback<ResponseModel<Blog[]>>()
- 请求成功
@Override
public void onResponse(Call<ResponseModel<Blog[]>> call, Response<ResponseModel<Blog[]>> response) {
if(response.body() != null){
if(response.body().getCode()==SUCCESS_CODE){
blogList.clear();
for(Blog i : response.body().getData()){
blogList.add(i);
}
MyBlogFragment.blogAdapter.notifyDataSetChanged();
MyBlogFragment.swipeRefreshLayout.setRefreshing(false);
}else {
Toast.makeText(MyApplication.getContext(), response.body().getMsg(), Toast.LENGTH_SHORT).show();
}
}
}
- 请求失败
@Override
public void onFailure(Call<ResponseModel<Blog[]>> call, Throwable t) {
Toast.makeText(MyApplication.getContext(),FAILED,Toast.LENGTH_SHORT).show();
if(dialog!=null){
dialog.dismiss();
}
}
其中通过response类的body()实现对返回数据的操作
问题和解决过程
- 问题1 在创建网络请求接口的时候会滥用注解,导致无法成功接收到服务器返回的数据
解决方法:统一网络请求方法,均用POST方法进行请求,具体的区别通过修改网络请求参数进行实现,尽量不用带缺省的方法,如弃用@Path进行URL的补充
- 问题2 异步请求的数据回调填充问题
如上的代码会有这么一段用于数据的回调填充
MyBlogFragment.blogAdapter.notifyDataSetChanged();
MyBlogFragment.swipeRefreshLayout.setRefreshing(false);
可以发现这个数据回调填充会针对特定的对象进行刷新,比如特定的adapter类blogAdapter以及特定的布局,一开始不会遇到这样的问题,但是在后期需要代码的复用的时候发现android在处理fragment与activity会存在一定的差异,导致在fragment能够实现的数据填充在activity中无法使用,同时,对不同的布局绑定了不同的adapter的话会出现无法刷新数据的情况,如下是实现相应刷新接口的方法
解决方法:在与前端组长商量过后只封装部分的调用方法在该类中,其他的存在问题的方法则直接在相关布局中调用,降低了实现的复杂性也不用考虑数据的回调填充的问题,但是降低了一定的封装性
流程图
总结
第一次接触Retrofit框架,由于仅仅是进行网络请求的封装,没有特别复杂的实现,挺容易上手的,就是前期的对相应的注解不够熟悉花了不少的时间去修改一些代码。之前在使用网络请求的时候用的是OkHttp会比较难理解,Retrofit会更好理解。遇到不会难以处理的问题也可以查找相关的资料进行解决,受益颇多。好好学习,天天向上吧。