Android网络访问库 - Retrofit学习(1)基础
Retrofit是什么
Retrofit是一个类型安全的HTTP客户端,支持Android和Java.它是Square公司开源的项目,当前版本2.0。
在实际开发中,我们Retrofit配合OKHTTP来使用。我们使用OKHTTP当做传输层,使用Retrofit在OKHTTP之上,使用Java的接口描述我们的HTTP协议。
简单的说: 使用Retrofit转换HTTP 的API协议成一个java的Interface服务,我们直接使用java类会方便好多。
Github: https://github.com/square/retrofit
当前版本2.1,本文会对比1.9来讲述2.x的特性。
Retrofit特点
- Retrofit将HTTP的API转换成java接口,并对接口生成默认的实现类。
- 支持同步和异步的调用方式
- 使用注解描述HTTP请求
- 对象转换,比如从json转换成java对象
- 支持多请求体(Multipart request body)和文件上传
类库和引用
添加依赖
在你的应用级别的gradle中添加:
compile 'com.squareup.retrofit2:retrofit:2.1.0'
一般情况下,我们还需要处理json格式的数据,那么我们需要一个转换器,你需要增加下面的依赖:
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
集成OKHTTP
为了避免重复引用OKHTTP,你还可以这么使用:
compile ('com.squareup.retrofit2:retrofit:2.1.0') {
// 排除依赖okhttp
exclude module: 'okhttp'
}
compile 'com.squareup.okhttp3:okhttp:3.3.1' //重新依赖okhttp
集成rxJava
如果你还想配合rxJava使用,你需要添加依赖:
compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'
compile 'io.reactivex:rxandroid:1.0.1'
在Retrofit2.x, RestAdapter 被改变为 Retrofit
Retrofit 1.9 时的写法
RestAdapter.Builder builder = new RestAdapter.Builder();
Retrofit 2.x的写法
Retrofit.Builder builder = new Retrofit.Builder();
配置URL地址
基础BaseUrl
基础url,就是你的服务器的地址,一般是个域名。比如你要访问 http://www.xxxx.com/user/list
我们在开发中使用相对url,即 /user/list,那么它的baseUrl就是 http://www.xxx.com
我们这样设置 baseUrl:
Retrofit retrofit = Retrofit.Builder()
.baseUrl(API_BASE_URL);
.build();
YourService service = retrofit.create(YourService.class);
Retrofit建议我们在设置 baseUrl时,以“/" 结尾。这样我们在指定相对路径的时候就不用写"/"了。
像下面这样:
public interface UserService {
@POST("me") //注意这里,没有 斜杠开头
Call<User>me();
}
Retrofit retrofit = Retrofit.Builder()
.baseUrl("https://your.api.url/v2/");//注意这里,以 斜杠结尾
.build();
UserService service = retrofit.create(UserService.class);
// the request url for service.me() is:
// https://your.api.url/v2/me
动态的url
有时候我们会以一些其他方式获得一个url,比如从数据库或者网络读取到一个url,这样的url就不能像上面那样 通过 baseUrl和相对url组合而成。
我们可以使用 "@Url" 注解来做,使用"@Url"对一个方法的参数进行注解,表明这是个url,示例:
public interface UserService {
@GET
public Call<File> getZipFile(@Url String url);
}
由OKHTTP驱动的拦截器Interceptors
使用拦截器处理自定义请求是一种很有用的方式。步骤:
1.自定义一个拦截器Interceptor
2.自定义一个OkHttpClient,调用 addInterceptor 方法,传入上面的拦截器
3.在构建Retrofit时, Retrofit.Builder 中,使用 .client() 方法. 传入OkHttpClient
示例:
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request original = chain.request();
// Customize the request
Request request = original.newBuilder()
.header("Accept", "application/json")
.header("Authorization", "auth-token")
.method(original.method(), original.body())
.build();
Response response = chain.proceed(request);
// Customize or return the response
return response;
}
});
OkHttpClient client = httpClient.build();
Retrofit retrofit = Retrofit.Builder()
.baseUrl("https://your.api.url/v2/");
.client(client)
.build();
请求的调用。 同步和异步,和终止
Retrofit 1.x 时,在服务接口的声明中,同步方法需要一个返回值,异步方式需要一个 Callback 的泛型参数作为最后一个参数。
而在 2.x 时,不再区分同步和异步调用,都被包裹在 一个泛型Call类中。
下面我们从 “接口定义” 和 “调用” 来对比他们的不同。
“接口定义”的区别
Retrofit 1.9 时
public interface UserService {
// 同步,有返回值
@POST("/login")
User login();
// 异步 Request,最后一个参数是 Callback 泛型
@POST("/login")
void getUser(@Query String id, Callback<User> cb);
}
而在 Retrofit 2.x 时
public interface UserService {
@POST("/login")
Call<User> login();
}
注意上面返回了一个Call的泛型。2.x不再以参数和返回值的方式区分异步同步的请求。
“调用”的区别
Retrofit 1.9 时
同步是直接调用。
而异步需要传入回调的实现。在实现里处理成功和失败的方法。
// 同步
User user = userService.login();
// 异步
userService.login(new Callback<User>() {
@Override
public void success(User user, Response response) {
// handle response
}
@Override
public void failure(RetrofitError error) {
// handle error
}
});
而在 Retrofit 2.x 时
同步是 调用 call.execute() 来获得结果。
异步是 调用 enqueue方法和传入回调。注意这里的回调 是onResponse 方法,不同于上面的成功和失败的方法。
这里的是onResponse 方法使用 response.isSuccessful()判断成功和失败。如果失败,使用 errorBody获得错误信息。
// 同步
Call<User> call = userService.login();
User user = call.execute().body();
// 异步
Call<User> call = userService.login();
call.enqueue(new Callback<User>() {
@Override
public void onResponse(Call<User> call, Response<User> response) {
// response.isSuccessful() is true if the response code is 2xx
if (response.isSuccessful()) {
User user = response.body();
} else {
int statusCode = response.code();
// handle request errors yourself
ResponseBody errorBody = response.errorBody();
}
}
@Override
public void onFailure(Call<User> call, Throwable t) {
// handle execution failures like no internet connectivity
}
}
取消/终止请求
在 Retrofit 1.9 是无法终止请求的。而在2.x ,你可以使用 cancel 来终止请求。
Call<User> call = userService.login();
User user = call.execute().body();
// changed your mind, cancel the request
call.cancel();
转换器
选择你需要的转换器
对比1.9提供默认的json转换器,Retrofit 2.x以后不在提供默认的转换器。比如你要使用json解析,
你可以使用gson转换器,添加库依赖:
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
Retrofit支持很多种转换器类型,根据你的需要,你可以通过gradle引用不同的扩展库:
Gson: com.squareup.retrofit2:converter-gson:2.1.0
Moshi: com.squareup.retrofit2:converter-moshi:2.1.0
Jackson: com.squareup.retrofit2:converter-jackson:2.1.0
SimpleXML: com.squareup.retrofit2:converter-simplexml:2.1.0
ProtoBuf: com.squareup.retrofit2:converter-protobuf:2.1.0
Wire: com.squareup.retrofit2:converter-wire:2.1.0
如果上面的转换器还不够你使用的话,你可以通过自己实现 Converter.Factory 来自定义转换器。
添加转换器到Retrofit对象
我们需要手动添加转换器到Retrofit对象上,使用addConverterFactory方法来添加一个ConverterFactory对象到Retrofit。
- 你可以根据你的需要选择不同的 转换器工厂(ConverterFactory).
- 你可以添加一个或者多个ConverterFactory,顺序很重要,Retrofit将会按顺序使用它,如果失败,就尝试使用下一个转换器。
示例:
Retrofit retrofit = Retrofit.Builder()
.baseUrl("https://your.api.url/v2/");
.addConverterFactory(ProtoConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
自定义转换器
请阅读 Retrofit converter implementations
集成 RxJava
依赖
Retrofit 1.9 集成了三种请求执行机制: 同步,异步,RxJava。而到了2.x后,仅仅保留了同步和异步机制。
Retrofit 2.x 提供了一种插件扩展的机制支持RxJava。要集成RxJava,你需要添加以下两个依赖,
第一个依赖是 CallAdapter 它以一种新的方式处理请求。你可以使用 Observable 作为接口声明的返回值。
第二个依赖是 AndroidSchedulers 类所需要的,它提供了 在Android主线程的调度方式。
compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'
compile 'io.reactivex:rxandroid:1.0.1'
使用
在构建Retrofit实例时,通过 addCallAdapterFactory 方法传入 CallAdapter。
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl);
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
接口声明时,返回一个 Observable 泛型对象。
public interface UserService {
@POST("/me")
Observable<User> me();
}
// this code is part of your activity/fragment
Observable<User> observable = userService.me();
observable
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(new Subscriber<User>() {
@Override
public void onCompleted() {
// 处理完成
}
@Override
public void onError(Throwable e) {
// 处理异常
}
@Override
public void onNext(User user) {
// 处理响应结果
}
});
不包含默认日志
Retrofit 本身没有提供日志功能,不过我们可以通过自定义okhttp的拦截器来实现它。你可以阅读这篇文章:
on how to get back logging into Retrofit 2
更新特性 WebSockets
Retrofit不提供 WebSockets 功能,不过OKHTTP提供了 WebSockets支持。
扩展资源
Jake Wharton’s talk @ Droidcon NYC 2015 on Retrofit 2
Details on OkHttp interceptors
Retrofit Converters
RxAndroid on GitHub
Retrofit CallAdapters
Retrofit Change Log
Android网络访问库 - Retrofit学习(1)基础的更多相关文章
- Android进阶笔记02:Android 网络请求库的比较及实战(二)
一.Volley 既然在android2.2之后不建议使用HttpClient,那么有没有一个库是android2.2及以下版本使用HttpClient,而android2.3及以上版本 ...
- Android进阶笔记01:Android 网络请求库的比较及实战(一)
在实际开发中,有的时候需要频繁的网络请求,而网络请求的方式很多,最常见的也就那么几个.本篇文章对常见的网络请求库进行一个总结. 一.使用HttpUrlConnection: 1. HttpUrlCon ...
- Android 网络请求框架Retrofit
Retrofit是Square公司开发的一款针对Android网络请求的框架,Retrofit2底层基于OkHttp实现的,OkHttp现在已经得到Google官方认可,大量的app都采用OkHttp ...
- android 网络请求库的比较
源码请戳 一. 现有库和选择的库 HttpURLConnection:是Java中的标准类,是对Java中socket的封装. Httpclient:是Apache的开源框架,是对HttpURLCon ...
- Android网络框架之Retrofit + RxJava + OkHttp 变化的时代
1.什么是Retrofit框架? 它是Square公司开发的现在非常流行的网络框架,所以我们在导入它的包的时候都可以看到这个公司的名字,目前的版本是2. 特点: 性能好,处理快,使用简单,Retrof ...
- 浅论Android网络请求库——android-async-http
在iOS开发中有大名鼎鼎的ASIHttpRequest库,用来处理网络请求操作,今天要介绍的是一个在Android上同样强大的网络请求库android-async-http,目前非常火的应用Insta ...
- Android网络请求库RetrofitUtils
RetrofitUtils GitHub地址,帮忙给个Star 项目介绍 Retrofit+Okhttp辅助类的简单封装,vesion 1.0.X 实现了Get,Post-Form.Post-Json ...
- android网络请求库volley方法详解
使用volley进行网络请求:需先将volley包导入androidstudio中 File下的Project Structrue,点加号导包 volley网络请求步骤: 1. 创建请求队列 ...
- Android 网络请求库volley的封装,让请求更方便
首先封装一下volley 请求 public class CustomRequest extends StringRequest { private static final String TAG = ...
随机推荐
- 【ASP.NET Web API教程】6.4 模型验证
本文是Web API系列教程的第6.4小节 6.4 Model Validation 6.4 模型验证 摘自:http://www.asp.net/web-api/overview/formats-a ...
- C语言 栈 链式结构 实现
一个C语言链式结构实现的栈 mStack (GCC编译). /** * @brief C语言实现的链式结构类型的栈 * @author wid * @date 2013-10-30 * * @note ...
- Nginx学习笔记(七) 创建子进程
Nginx创建子进程 ngx_start_worker_processes位于Nginx_process_cycle.c中,主要的工作是创建子进程. 在Nginx中,master进程和worker进程 ...
- [JAVA] 一个可以编辑、编译、运行Java简单文件的记事本java实现
本来是Java课做一个仿windows记事本的实验,后来突然脑子一热,结果就给它加了一个编译运行Java文件的功能. 本工程总共大约3000行代码,基本上把所学的java界面.文件.控件的功能都包含在 ...
- eclipse 远程调试
http://blog.sina.com.cn/s/blog_86a6730b0101iean.html 注:远程服务器端可用以下方式替代: iptables -I from_external 3 - ...
- Atitit selenium3 新特性
Atitit selenium3 新特性 Selenium2.0 支持了webdriver api,,原来自己的api放弃了. Selenium v2.45.0 发布,支持Firefox 3 ...
- iOS上应用如何兼容32位系统和64位系统
在苹果推出iPhone5S时,64位的应用就走到了眼前.当时就看见苹果官方资料宣布iOS7.x的SDK支持了64位的应用,而且内置的应用都已经是64位. 我记得自己刚刚接触电脑时还有16位的系统,指针 ...
- bzoj 1191: [HNOI2006]超级英雄Hero
1191: [HNOI2006]超级英雄Hero Time Limit: 10 Sec Memory Limit: 162 MB 二分图匹配... Description 现在电视台有一种节目叫做超 ...
- 【Python排序搜索基本算法】之深度优先搜索、广度优先搜索、拓扑排序、强联通&Kosaraju算法
Graph Search and Connectivity Generic Graph Search Goals 1. find everything findable 2. don't explor ...
- JPA的事务注解@Transactional使用总结
在项目开发过程中,如果您的项目中使用了Spring的@Transactional注解,有时候会出现一些奇怪的问题,例如: 明明抛了异常却不回滚? 嵌套事务执行报错? ...等等 很多的问题都是没有全面 ...