前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android网络访问库 - Retrofit学习(1)基础

Android网络访问库 - Retrofit学习(1)基础

作者头像
张云飞Vir
发布2020-03-16 16:07:36
9560
发布2020-03-16 16:07:36
举报
文章被收录于专栏:写代码和思考写代码和思考

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中添加:

代码语言:javascript
复制
compile 'com.squareup.retrofit2:retrofit:2.1.0'  

一般情况下,我们还需要处理json格式的数据,那么我们需要一个转换器,你需要增加下面的依赖:

代码语言:javascript
复制
compile 'com.squareup.retrofit2:converter-gson:2.1.0'  

集成OKHTTP

为了避免重复引用OKHTTP,你还可以这么使用:

代码语言:javascript
复制
compile ('com.squareup.retrofit2:retrofit:2.1.0') {  
  // 排除依赖okhttp
  exclude module: 'okhttp'
}
compile 'com.squareup.okhttp3:okhttp:3.3.1' //重新依赖okhttp

集成rxJava

如果你还想配合rxJava使用,你需要添加依赖:

代码语言:javascript
复制
compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'  
compile 'io.reactivex:rxandroid:1.0.1'  

在Retrofit2.x, RestAdapter 被改变为 Retrofit

Retrofit 1.9 时的写法

代码语言:javascript
复制
RestAdapter.Builder builder = new RestAdapter.Builder();  

Retrofit 2.x的写法

代码语言:javascript
复制
Retrofit.Builder builder = new Retrofit.Builder();  

配置URL地址

基础BaseUrl

基础url,就是你的服务器的地址,一般是个域名。比如你要访问 http://www.xxxx.com/user/list 我们在开发中使用相对url,即 /user/list,那么它的baseUrl就是 http://www.xxx.com 我们这样设置 baseUrl:

代码语言:javascript
复制
Retrofit retrofit = Retrofit.Builder()  
    .baseUrl(API_BASE_URL);
    .build();

YourService service = retrofit.create(YourService.class);  

Retrofit建议我们在设置 baseUrl时,以“/" 结尾。这样我们在指定相对路径的时候就不用写"/"了。 像下面这样:

代码语言:javascript
复制
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,示例:

代码语言:javascript
复制
public interface UserService {  
    @GET
    public Call<File> getZipFile(@Url String url);
}

由OKHTTP驱动的拦截器Interceptors

使用拦截器处理自定义请求是一种很有用的方式。步骤: 1.自定义一个拦截器Interceptor 2.自定义一个OkHttpClient,调用 addInterceptor 方法,传入上面的拦截器 3.在构建Retrofit时, Retrofit.Builder 中,使用 .client() 方法. 传入OkHttpClient 示例:

代码语言:javascript
复制
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 时

代码语言:javascript
复制
public interface UserService {  
    // 同步,有返回值
    @POST("/login")
    User login();

    // 异步 Request,最后一个参数是 Callback 泛型
    @POST("/login")
    void getUser(@Query String id, Callback<User> cb);
}

而在 Retrofit 2.x 时

代码语言:javascript
复制
public interface UserService {  
    @POST("/login")
    Call<User> login();
}

注意上面返回了一个Call的泛型。2.x不再以参数和返回值的方式区分异步同步的请求。

“调用”的区别

Retrofit 1.9 时 同步是直接调用。 而异步需要传入回调的实现。在实现里处理成功和失败的方法。

代码语言:javascript
复制
// 同步
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获得错误信息。

代码语言:javascript
复制
// 同步
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 来终止请求。

代码语言:javascript
复制
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转换器,添加库依赖:

代码语言:javascript
复制
compile 'com.squareup.retrofit2:converter-gson:2.1.0'  

Retrofit支持很多种转换器类型,根据你的需要,你可以通过gradle引用不同的扩展库:

代码语言:javascript
复制
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将会按顺序使用它,如果失败,就尝试使用下一个转换器。

示例:

代码语言:javascript
复制
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<T> 作为接口声明的返回值。 第二个依赖是 AndroidSchedulers 类所需要的,它提供了 在Android主线程的调度方式。

代码语言:javascript
复制
compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'  
compile 'io.reactivex:rxandroid:1.0.1'  

使用

在构建Retrofit实例时,通过 addCallAdapterFactory 方法传入 CallAdapter。

代码语言:javascript
复制
Retrofit retrofit = new Retrofit.Builder()  
    .baseUrl(baseUrl);
    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
    .addConverterFactory(GsonConverterFactory.create())
    .build();

接口声明时,返回一个 Observable<User> 泛型对象。

代码语言:javascript
复制
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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Retrofit是什么
  • Retrofit特点
  • 类库和引用
    • 添加依赖
      • 集成OKHTTP
        • 集成rxJava
        • 在Retrofit2.x, RestAdapter 被改变为 Retrofit
        • 配置URL地址
          • 基础BaseUrl
            • 动态的url
            • 由OKHTTP驱动的拦截器Interceptors
            • 请求的调用。 同步和异步,和终止
              • “接口定义”的区别
                • “调用”的区别
                  • 取消/终止请求
                  • 转换器
                    • 选择你需要的转换器
                      • 添加转换器到Retrofit对象
                        • 自定义转换器
                        • 集成 RxJava
                          • 依赖
                            • 使用
                            • 不包含默认日志
                            • 更新特性 WebSockets
                            • 扩展资源
                            领券
                            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档