Retrofit是一个类型安全的HTTP客户端,支持Android和Java.它是Square公司开源的项目,当前版本2.0。java
在实际开发中,咱们Retrofit配合OKHTTP来使用。咱们使用OKHTTP当作传输层,使用Retrofit在OKHTTP之上,使用Java的接口描述咱们的HTTP协议。
简单的说: 使用Retrofit转换HTTP 的API协议成一个java的Interface服务,咱们直接使用java类会方便好多。react
Github: https://github.com/square/retrofitandroid
当前版本2.1,本文会对比1.9来说述2.x的特性。git
在你的应用级别的gradle中添加:github
compile 'com.squareup.retrofit2:retrofit:2.1.0'
通常状况下,咱们还须要处理json格式的数据,那么咱们须要一个转换器,你须要增长下面的依赖:web
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
为了不重复引用OKHTTP,你还能够这么使用:数据库
compile ('com.squareup.retrofit2:retrofit:2.1.0') { // 排除依赖okhttp exclude module: 'okhttp' } compile 'com.squareup.okhttp3:okhttp:3.3.1' //从新依赖okhttp
若是你还想配合rxJava使用,你须要添加依赖:json
compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0' compile 'io.reactivex:rxandroid:1.0.1'
Retrofit 1.9 时的写法api
RestAdapter.Builder builder = new RestAdapter.Builder();
Retrofit 2.x的写法安全
Retrofit.Builder builder = new Retrofit.Builder();
基础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就不能像上面那样 经过 baseUrl和相对url组合而成。
咱们可使用 "@Url" 注解来作,使用"@Url"对一个方法的参数进行注解,代表这是个url,示例:
public interface UserService { @GET public Call<File> getZipFile(@Url String url); }
使用拦截器处理自定义请求是一种颇有用的方式。步骤:
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对象上,使用addConverterFactory方法来添加一个ConverterFactory对象到Retrofit。
示例:
Retrofit retrofit = Retrofit.Builder() .baseUrl("https://your.api.url/v2/"); .addConverterFactory(ProtoConverterFactory.create()) .addConverterFactory(GsonConverterFactory.create()) .build();
请阅读 Retrofit converter implementations
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
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