程序员之家爱情与面包RxJava

Android:Retrofit 结合 RxJava的优雅使用(

2018-01-09  本文已影响3311人  Carson带你学安卓

前言

Github截图 Github截图

本文主要基于Retrofit 2.0 & Rxjava 2.0

  1. 本系列文章主要基于 Rxjava 2.0
  2. 接下来的时间,我将持续推出 AndroidRxjava 2.0 的一系列文章,包括原理、操作符、应用场景、背压等等 ,有兴趣可以继续关注Carson_Ho的安卓开发笔记!!
示意图

目录

示意图

1. Retrofit 简介

示意图

特别注意:

关于Retrofit的更加详细介绍请看文章:这是一份很详细的 Retrofit 2.0 使用教程(含实例讲解)


2. RxJava简介

示意图

关于RxJava的更加详细介绍请看文章:Android Rxjava:这是一篇 清晰 & 易懂的Rxjava 入门教程


3. 二者结合使用

即:Retrofit除了提供传统的网络请求方式外,还提供 RxJava 版本的 网络请求方式

a. 用于描述网络请求 的接口设置

// 传统方式:Call<..>接口形式
public interface GetRequest_Interface {
 @GET("url地址")
    Call<Translation> getCall();
    // 注解里传入 网络请求 的部分URL地址
    // getCall()是接受网络请求数据的方法
}

//  RxJava 方式:Observable<..>接口形式
 @GET("url地址")
public interface GetRequest_Interface {
Observable<Translation> getCall();

b. 网络请求的封装形式 & 发送形式不同

<-- 传统方式 ->>
        // 1. 创建 网络请求接口 的实例
        GetRequest_Interface request = retrofit.create(GetRequest_Interface.class);

        // 2. 采用Call<..>接口 对 发送请求 进行封装
        Call<Translation> call = request.getCall();

        // 3. 发送网络请求(异步)
        call.enqueue(new Callback<Translation>() {
            // 请求成功时回调
            @Override
            public void onResponse(Call<Translation> call, Response<Translation> response) {
                 ...  
            }

            // 请求失败时回调
            @Override
            public void onFailure(Call<Translation> call, Throwable throwable) {
                ....
            }
        });


<-- RxJava 版方式 ->>
        // 1. 创建 网络请求接口 的实例
        GetRequest_Interface request = retrofit.create(GetRequest_Interface.class);

        // 2. 采用Observable<...>形式 对 网络请求 进行封装
        Observable<Translation> observable = request.getCall();
        
        // 3. 发送网络请求(异步)
        observable.subscribeOn(Schedulers.io())               // 在IO线程进行网络请求
                  .observeOn(AndroidSchedulers.mainThread())  // 回到主线程 处理请求结果
                  .subscribe(new Observer<Translation>() {

                    // 发送请求后调用该复写方法(无论请求成功与否)
                    @Override
                    public void onSubscribe(Disposable d) {
                        ...// 初始化工作
                      }
                    
                    // 发送请求成功后调用该复写方法
                    @Override
                    public void onNext(Translation result) {
                        ...// 对返回结果Translation类对象 进行处理
                    }

                    // 发送请求成功后,先调用onNext()再调用该复写方法
                    @Override
                    public void onComplete() {
                        Log.d(TAG, "请求成功");
                    }
                    // 发送请求失败后调用该复写方法
                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "请求失败");
                    }

                });
    }


4. 基础使用

下面,我将采用最基础的 Retrofit + RxJava 实现 网络请求 的功能

4.1 功能说明

  1. 先切换到工作线程 发送网络请求
  2. 再切换到主线程进行 UI更新
金山词典

4.2 步骤说明

  1. 添加依赖
  2. 创建 接收服务器返回数据 的类
  3. 创建 用于描述网络请求 的接口(区别于传统形式)
  4. 创建 Retrofit 实例
  5. 创建 网络请求接口实例 并 配置网络请求参数(区别于传统形式)
  6. 发送网络请求(区别于传统形式)
  7. 发送网络请求
  8. 对返回的数据进行处理

本实例侧重于说明 RxJava 的线程控制,关于Retrofit的使用请看文章:这是一份很详细的 Retrofit 2.0 使用教程(含实例讲解)

4.3 步骤实现

步骤1: 添加依赖

a. 在 Gradle加入Retrofit库的依赖

build.gradle

dependencies {

// Android 支持 Rxjava
// 此处一定要注意使用RxJava2的版本
compile 'io.reactivex.rxjava2:rxjava:2.0.1'
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'

// Android 支持 Retrofit
compile 'com.squareup.retrofit2:retrofit:2.1.0'

// 衔接 Retrofit & RxJava
// 此处一定要注意使用RxJava2的版本
compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'

// 支持Gson解析
compile 'com.squareup.retrofit2:converter-gson:2.1.0'

}

b. 添加 网络权限
AndroidManifest.xml

<uses-permission android:name="android.permission.INTERNET"/>
步骤2:创建 接收服务器返回数据 的类
// URL模板
http://fy.iciba.com/ajax.php

// URL实例
http://fy.iciba.com/ajax.php?a=fy&f=auto&t=auto&w=hello%20world

// 参数说明:
// a:固定值 fy
// f:原文内容类型,日语取 ja,中文取 zh,英语取 en,韩语取 ko,德语取 de,西班牙语取 es,法语取 fr,自动则取 auto
// t:译文内容类型,日语取 ja,中文取 zh,英语取 en,韩语取 ko,德语取 de,西班牙语取 es,法语取 fr,自动则取 auto
// w:查询内容
API格式说明

Translation.java

public class Translation {
    private int status;

    private content content;
    private static class content {
        private String from;
        private String to;
        private String vendor;
        private String out;
        private int errNo;
    }

    //定义 输出返回数据 的方法
    public void show() {
        System.out.println( "Rxjava翻译结果:" + status);
        System.out.println("Rxjava翻译结果:" + content.from);
        System.out.println("Rxjava翻译结果:" + content.to);
        System.out.println("Rxjava翻译结果:" + content.vendor);
        System.out.println("Rxjava翻译结果:" + content.out);
        System.out.println("Rxjava翻译结果:" + content.errNo);
    }
}
步骤3:创建 用于描述网络请求 的接口

采用 注解 + Observable<...>接口描述 网络请求参数

GetRequest_Interface.java

public interface GetRequest_Interface {

    @GET("ajax.php?a=fy&f=auto&t=auto&w=hi%20world")
    Observable<Translation> getCall();
     // 注解里传入 网络请求 的部分URL地址
    // Retrofit把网络请求的URL分成了两部分:一部分放在Retrofit对象里,另一部分放在网络请求接口里
    // 如果接口里的url是一个完整的网址,那么放在Retrofit对象里的URL可以忽略
    // 采用Observable<...>接口 
    // getCall()是接受网络请求数据的方法
}
接下来的步骤均在MainActivity.java内实现(请看注释)

MainActivity.java

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "Rxjava";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //步骤4:创建Retrofit对象
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://fy.iciba.com/") // 设置 网络请求 Url
                .addConverterFactory(GsonConverterFactory.create()) //设置使用Gson解析(记得加入依赖)
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) // 支持RxJava
                .build();

        // 步骤5:创建 网络请求接口 的实例
        GetRequest_Interface request = retrofit.create(GetRequest_Interface.class);

        // 步骤6:采用Observable<...>形式 对 网络请求 进行封装
        Observable<Translation> observable = request.getCall();

        // 步骤7:发送网络请求
        observable.subscribeOn(Schedulers.io())               // 在IO线程进行网络请求
                  .observeOn(AndroidSchedulers.mainThread())  // 回到主线程 处理请求结果
                  .subscribe(new Observer<Translation>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.d(TAG, "开始采用subscribe连接");
                    }

                    @Override
                    public void onNext(Translation result) {
                        // 步骤8:对返回的数据进行处理
                        result.show() ;
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "请求失败");
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, "请求成功");
                    }
                });
    }
}

4.4 测试结果

示意图

4.5 Demo地址

Carson_Ho的Github地址 = Retrofit结合RxJava实战系列:基础使用


5. 实际开发需求案例

示意图

5.1 网络请求轮询(无条件)

示意图

5.2 网路请求轮询(有条件)

示意图

5.3 网络请求嵌套回调

如 先进行 用户注册 的网络请求, 待注册成功后回再继续发送 用户登录 的网络请求

下面展示的是结合 RetrofitRxJava的基本用法,即未用操作符前

// 发送注册网络请求的函数方法
    private void register() {
        api.register(new RegisterRequest())
                .subscribeOn(Schedulers.io())               //在IO线程进行网络请求
                .observeOn(AndroidSchedulers.mainThread())  //回到主线程去处理请求结果
                .subscribe(new Consumer<RegisterResponse>() {
                    @Override
                    public void accept(RegisterResponse registerResponse) throws Exception {
                        Toast.makeText(MainActivity.this, "注册成功", Toast.LENGTH_SHORT).show();
                        login();   //注册成功, 调用登录的方法
                    }
                }, new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) throws Exception {
                        Toast.makeText(MainActivity.this, "注册失败", Toast.LENGTH_SHORT).show();
                    }
                });
    }


// 发送登录网络请求的函数方法
private void login() {
        api.login(new LoginRequest())
                .subscribeOn(Schedulers.io())               //在IO线程进行网络请求
                .observeOn(AndroidSchedulers.mainThread())  //回到主线程去处理请求结果
                .subscribe(new Consumer<LoginResponse>() {
                    @Override
                    public void accept(LoginResponse loginResponse) throws Exception {
                        Toast.makeText(MainActivity.this, "登录成功", Toast.LENGTH_SHORT).show();
                    }
                }, new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) throws Exception {
                        Toast.makeText(MainActivity.this, "登录失败", Toast.LENGTH_SHORT).show();
                    }
                });
    }


5.4 网络请求出错重连

示意图 示意图

5.5 合并数据源 & 统一显示

示意图

至此,关于Retrofit & RxJava的实际开发需求场景讲解完毕。


6. Demo地址

上述所有案例的源代码都存放在:Carson_Ho的Github地址 = Retrofit结合RxJava实战系列


7. 总结


请点赞!因为你的鼓励是我写作的最大动力!

相关文章阅读


欢迎关注Carson_Ho的简书!

不定期分享关于安卓开发的干货,追求短、平、快,但却不缺深度

上一篇下一篇

猜你喜欢

热点阅读