网络请求框架,自从开发以来经历过多个网络访问框架了HttpURLConnection---> HttpClient--->Async Http Client--->Volley--->okhttp
以上这些不做重点介绍,以后可能会单独发个博客来对比他们的优缺点,想当初刚开始接触网络请求最先用的就是HttpURLConnection ,还用这个api写了个多线程断点续传,想想都是回忆啊...现在回过头来看,最次的都是用Volley,大部分都是用okhttp前面几种估计也没公司用了,今天重点就是介绍Retrofit
1 什么是Retrofit?
说白了Retrofit就是包装了okhttp(也可以包装其他网络请求框架,默认是okhttp)的壳子,用来帮我们简化 网络请求的代码,并且是基于注解,使用更加方便!有人会有疑问,本来网络请求框架如okhttp 就是对网络请求的封装了,为什么还要封装一层?这是为了简化屏蔽掉一些网络请求的代码,比如我们用的是volley,如果想换成okhttp是不是要到代码去改只要用到网络请求的代码就要改成okhtp,但是现在如果封装一层,是不是,我只要改一处,就可以实现替换网络请求的框架?
现在应该明白了Retrofit作用了吧?就是基于注解对网络框架的封装!
okhttp和Retrofit在实际开发中的对比http://blog.csdn.net/u012600955/article/details/62045531
写个Demo给大家,以我公司的的软件升级地址为例(关键部分xxx代替)
通过GET请求到服务器最新软件版本
请求的地址:htp://xxxx.xxx.com/xxxx/version/android/2.7.1
通过返回的json转成bean对象,判断是否需要更新应用
响应结果:
当软件已经是最新的返回json为
{
"status" : 0,
"msg" : "",
"version" : 2.7.1
}
当前软件为旧版本
{
"status" : 1,
"msg" : ""更新的功能等描述"",
"version" : 2.8.0
}
首先介绍下标准写法,也就是完整的Retrofit使用方式,但是不推荐,然后会介绍第二种简便方式,学东西肯定要学好基础,在学升级版,不是么?
方法一
1 首先AndroidStudio的gradle配置依赖包
compile 'com.squareup.retrofit:retrofit:2.0.0-beta2' compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2'
2 创建Retrofit对象用于配置网络协议,主机名,数据转换信息等
Retrofit retrofit=new Retrofit.Builder().baseUrl("htp://xxxx.xxx.com/xxxx/")//配置主机地址 .addConverterFactory(GsonConverterFactory.create()).build();//配置数据转换器3 创建一个接口定义数据请求路径以及数据返回类型
import retrofit.Call; import retrofit.http.GET; import retrofit.http.Path; /** * */ public interface ServicesDemo { @GET("android/2.7.1")//注释的GET如果是GET请求就写GET是POST请求就写POST Call<VersionBean> loadVersionInfo(); //可以看到我这里已经把版本号写死了,而一般不推荐写死,
一般是调用api获取版本号作为参数传入 //那么就要这么写了,上面是我图方便,这么些表示参数指向的就是version,传什么上面的version字符串就是什么 @GET("android/{version}") Call<VersionBean> loadVersionInfo(@Path("version") String version); }以上只是其中一种注解使用方式
4 Retrofit对象获取接口实现类
//通过retrofit生成接口的实现类,这个实现类是一个动态代理(无需理解,会用就行) ServicesDemo servicesDemo = retrofit.create(ServicesDemo.class);
5 实现类调用接口中的方法
//这个代理类就可以调用接口函数和服务器交互 Call<VersionBean> versionBeanCall = servicesDemo.loadVersionInfo();
6 最后获取数据
// Response<VersionBean> execute = versionBeanCall.execute();同步 阻塞时获取数据,
需要开子线程,一般现在不推荐用 //异步获取数据,数据获取并解析完毕时onResponse回调 versionBeanCall.enqueue(new Callback<VersionBean>() { @Override public void onResponse(Response<VersionBean> response, Retrofit retrofit) { } @Override public void onFailure(Throwable t) { } }); } }是不是感觉有点复杂了,但这是Retrofit的完成调用方式,实际开发不会写这么复杂,所以这里介绍第二种方式,上面只是告诉你Retrofit的使用方式
方法二
就是对上面的代码进行一下封装,调用更方便,所以说要明白方法一,方法一是基石,方法二是升级版
1 创建一个类对方法一进行封装,将回调作为参数传入,以后我们只要在ServicesDemo接口中声明所有的网络请求方式,请求参数,请求数据类型
public class ServiceDemoExpert { static Retrofit retrofit=new Retrofit.Builder().baseUrl("htp://xxxx.xxx.com/xxxx/version/")//配置主机地址 .addConverterFactory(GsonConverterFactory.create()).build();//配置数据转换器 //通过retrofit生成接口的实现类,这个实现类是一个动态代理(无需理解,会用就行) static ServicesDemo servicesDemo = retrofit.create(ServicesDemo.class); public static void loadVersion(Callback<VersionBean> callback){ Call<VersionBean> versionBeanCall = servicesDemo.loadVersionInfo(); versionBeanCall.enqueue(callback); } }以后使用非常简单,因为是静态,连对象都不用new了
ServiceDemoExpert.loadVersion(new Callback<VersionBean>() { @Override public void onResponse(Response<VersionBean> response, Retrofit retrofit) { } @Override public void onFailure(Throwable t) { } });
大家要记住,所有的请求,都要配置在接口中,当然注解也不止这一种注解,使用上都大同小异,不做过多的说明了
// 可以直接在URL中指定参数
@GET("version/android/2.3.0?order=desc")
Call<VersionInfoDTO> loadVersionInfo();
// 可以添加参数,相当于在链接后面添加了键值对
@GET("version/android/2.3.0")
Call<VersionInfoDTO> loadVersionInfo(@Query("order") String order);
// 可以添加占位符
@GET("news/before/{dateStr}") // 表示{dateStr}由函数参数决定
Call<NewsBeforeDTO> getNewsBefore(@Path("dateStr") String date); // dateStr要一致
// 设置POST请求体
@POST("users/new")
void createUser(@Body User user, Callback<User> cb);
// 上传POST表单数据
@FormUrlEncoded
@POST("user/edit")
User updateUser(@Field("name") String name, @Field("age") int age);
// 多文件/数据上传
@Multipart
@PUT("/user/photo")
Call<User> updateUser(@Part("photo") RequestBody photo, @Part("description") RequestBody description);
//给当前请求添加Headers头信息
@Headers({
"Accept: applicationnd/vnd.github.v3.full+json",
"User-Agent: Retrofit-Sample-App"
})
@GET("version/android/2.3.0")
Call<VersionInfoDTO> loadVersionInfo();
当然,上传稍微复杂,以后会抽时间讲解下
这里提供 Jake Wharton 对Retrofit的介绍 这里比大多数网上的介绍都要详细,I Believe!
http://www.jsonschema2pojo.org/