Android之RxJava原理剖析

415 阅读13分钟

说明

该文档不是介绍如何使用RxJava,如要详细地使用RxJava请参考下面的参考文档。整个文档比较抽象,说明得不够细致,如果有不明白的地方可以查看其他文档或者评论区交流。建议先结合使用文档再浏览该文档,并且细读,希望能给大家提供帮助。

参考文档

入门

基础相关

RxJava2.0与RxJava3.0差异化

1.RxJava应用场景

核心思想

传统思维

 // 传统方式 思维 无法固定 (后面接手你写的项目,看不懂)
    // A程序员:35356453 自己的思维 不同  封装方法....
    // B程序员:46576576 自己的思维 不同  全部写在一起
    // C程序员:43643654 自己的思维 不同  new Thread
    // D程序员:66545655 自己的思维 不同  使用 线程池
    // ...
    // 零零散散 麻烦  思维
    public void downloadImageAction(View view) {
        progressDialog = new ProgressDialog(this);
        progressDialog.setTitle("下载图片中...");
        progressDialog.show();

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    URL url = new URL(PATH);
                    HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
                    httpURLConnection.setConnectTimeout(5000);
                    int responseCode = httpURLConnection.getResponseCode(); // 才开始 request
                    if (responseCode == HttpURLConnection.HTTP_OK) {
                        InputStream inputStream = httpURLConnection.getInputStream();
                        Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
                        Message message = handler.obtainMessage();
                        message.obj = bitmap;
                        handler.sendMessage(message);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    private final Handler handler = new Handler(new Handler.Callback() {

        @Override
        public boolean handleMessage(@NonNull Message msg) {
            Bitmap bitmap = (Bitmap) msg.obj;
            image.setImageBitmap(bitmap);

            if (progressDialog != null) progressDialog.dismiss();
            return false;
        }
    });

RxJava思维

 /**
     * 封装我们的操作
     * upstream   上游
     * d
     */
    public final static <UD> ObservableTransformer<UD, UD> rxud() {
        return new ObservableTransformer<UD, UD>() {
            @Override
            public ObservableSource<UD> apply(Observable<UD> upstream) {
                return  upstream.subscribeOn(Schedulers.io())     // 给上面代码分配异步线程
                .observeOn(AndroidSchedulers.mainThread()) // 给下面代码分配主线程;
                .map(new Function<UD, UD>() {
                    @Override
                    public UD apply(UD ud) throws Exception {
                        Log.d(TAG, "apply: 我监听到你了,居然再执行");
                        return ud;
                    }
                });
                // .....        ;
            }
        };
    }

    public void rxJavaDownloadImageAction(View view) {
        // 起点
        Observable.just(PATH)  // 内部会分发  PATH Stirng  // TODO 第二步

         // TODO 第三步
        .map(new Function<String, Bitmap>() {
            @Override
            public Bitmap apply(String s) throws Exception {
                URL url = new URL(PATH);
                HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
                httpURLConnection.setConnectTimeout(5000);
                int responseCode = httpURLConnection.getResponseCode(); // 才开始 request
                if (responseCode == HttpURLConnection.HTTP_OK) {
                    InputStream inputStream = httpURLConnection.getInputStream();
                    Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
                    return bitmap;
                }
                return null;
            }
        })
        /*.map(new Function<Bitmap, Bitmap>() {
            @Override
            public Bitmap apply(Bitmap bitmap) throws Exception {
                Paint paint = new Paint();
                paint.setTextSize(88);
                paint.setColor(Color.RED);
                return drawTextToBitmap(bitmap, "水印",paint, 88 , 88);
            }
        })*/
        
        // 日志记录
        .map(new Function<Bitmap, Bitmap>() {
            @Override
            public Bitmap apply(Bitmap bitmap) throws Exception {
                Log.d(TAG, "apply: 是这个时候下载了图片啊:" + System.currentTimeMillis());
                return bitmap;
            }
        })

        .compose(rxud())

        // 订阅 起点 和 终点 订阅起来
        .subscribe(
                // 终点
                new Observer<Bitmap>() {
                    // 订阅开始
                    @Override
                    public void onSubscribe(Disposable d) {
                        // 预备 开始 要分发
                        // TODO 第一步
                        progressDialog = new ProgressDialog(DownloadActivity.this);
                        progressDialog.setTitle("download run");
                        progressDialog.show();
                    }

                    // TODO 第四步
                    // 拿到事件
                    @Override
                    public void onNext(Bitmap bitmap) {
                        image.setImageBitmap(bitmap);
                    }

                    // 错误事件
                    @Override
                    public void onError(Throwable e) {

                    }

                    // TODO 第五步
                    // 完成事件
                    @Override
                    public void onComplete() {
                        if (progressDialog != null)
                            progressDialog.dismiss();
                    }
        });

    }

RxJava配合Retrofit

    private api = HttpUtil.getOnlineCookieRetrofit().create(WangAndroidApi.class);

/**
     * TODO Retrofit+RxJava 查询 项目分类  (总数据查询)
     *
     * @param view
     */
    public void getProjectAction(View view) {
        // 获取网络API
        api.getProject()
                .subscribeOn(Schedulers.io()) // 上面 异步
                .observeOn(AndroidSchedulers.mainThread()) // 下面 主线程
                .subscribe(new Consumer<ProjectBean>() {
                    @Override
                    public void accept(ProjectBean projectBean) throws Exception {
                        Log.d(TAG, "accept: " + projectBean); // UI 可以做事情
                    }
                });
    }

    /**
     * TODO Retrofit+RxJava 查询  项目分类的49 去 获取项目列表数据  (Item)
     *
     * @param view
     */
    public void getProjectListAction(View view) {
        // 注意:这里的 294 是项目分类 所查询出来的数据
        // 上面的项目分类会查询出:"id": 294,"id": 402,"id": 367,"id": 323,"id": 314, ...

        // id 写死的
        api.getProjectItem(1, 294)
                // .....可以添加其他操作
                .subscribeOn(Schedulers.io()) // 上面 异步
                .observeOn(AndroidSchedulers.mainThread()) // 下面 主线程
                .subscribe(data->{
                    Log.d(TAG, "getProjectListAction: " + data);
                });

    }
public interface WangAndroidApi {

    // 总数据
    @GET("project/tree/json")
    Observable<ProjectBean> getProject();  // 异步线程 耗时操作

    // ITem数据
    @GET("project/list/{pageIndex}/json") // ?cid=294
    Observable<ProjectItem> getProjectItem(@Path("pageIndex") int pageIndex, @Query("cid") int cid);  // 异步线程 耗时操作
}
public class HttpUtil {

    private static final String TAG = "HttpUtils";

    /**
     * 默认 test-a环境
     */
    public static String BASE_URL = "https://www.wanandroid.com/";

    public static void setBaseUrl(String baseUrl) {
        BASE_URL = baseUrl;
    }

    /**
     * 根据各种配置创建出Retrofit
     *
     * @return 返回创建好的Retrofit
     */
    public static Retrofit getOnlineCookieRetrofit() {
        // OKHttp客户端
        OkHttpClient.Builder httpBuilder = new OkHttpClient.Builder();
        // 各种参数配置
        OkHttpClient okHttpClient = httpBuilder
                .addNetworkInterceptor(new StethoInterceptor())
                .readTimeout(10000, TimeUnit.SECONDS)
                .connectTimeout(10000, TimeUnit.SECONDS)
                .writeTimeout(10000, TimeUnit.SECONDS)
                .build();


        return new Retrofit.Builder().baseUrl(BASE_URL)
                // TODO 请求用 OKhttp
                .client(okHttpClient)

                // TODO 响应RxJava
                // 添加一个json解析的工具
                .addConverterFactory(GsonConverterFactory.create(new Gson()))
                // 添加rxjava处理工具
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())

                .build();
    }
}

防抖

implementation 'com.jakewharton.rxbinding2:rxbinding:2.1.1' // 操作功能防抖
/**
     * RxJava
     * RxJs
     * Rxxxxx
     * RxBinding  防抖
     *
     * TODO 功能防抖 + 网络嵌套(这种是负面教程,嵌套的太厉害了)
     * 2层嵌套
     * 6层
     */
    @SuppressLint("CheckResult")
    private void antiShakeActon() {
        // 注意:(项目分类)查询的id,通过此id再去查询(项目列表数据)

        // 对那个控件防抖动?
        Button bt_anti_shake = findViewById(R.id.bt_anti_shake);

        RxView.clicks(bt_anti_shake)
                .throttleFirst(2000, TimeUnit.MILLISECONDS) // 2秒钟之内 响应你一次
                .subscribe(new Consumer<Object>() {
                    @Override
                    public void accept(Object o) throws Exception {
                        api.getProject() // 查询主数据
                        .compose(DownloadActivity.rxud())
                        .subscribe(new Consumer<ProjectBean>() {
                            @Override
                            public void accept(ProjectBean projectBean) throws Exception {
                                for (ProjectBean.DataBean dataBean : projectBean.getData()) { // 10
                                    // 查询item数据
                                    api.getProjectItem(1, dataBean.getId())
                                    .compose(DownloadActivity.rxud())
                                    .subscribe(new Consumer<ProjectItem>() {
                                        @Override
                                        public void accept(ProjectItem projectItem) throws Exception {
                                            Log.d(TAG, "accept: " + projectItem); // 可以UI操作
                                        }
                                    });
                                }
                            }
                        });
                    }
                });
    }

网络嵌套

起点可以分发一个数据
onNext(1);
    |
    |
    |
flatMap  自己分发 10个数据 给下面,不用for循环处理
 1 --> 多发送 101+"DDD"
    |
    |
    |
subscribe{
    1+"DDD"
    1+"DDD"
    1+"DDD"
    1+"DDD"
    1+"DDD"
    1+"DDD"
    1+"DDD"
    1+"DDD"
    1+"DDD"
    1+"DDD"
}
 /**
     * TODO 功能防抖 + 网络嵌套 (解决嵌套的问题) flatMap
     */
    @SuppressLint("CheckResult")
    private void antiShakeActonUpdate() {
        // 注意:项目分类查询的id,通过此id再去查询(项目列表数据)

        // 对那个控件防抖动?
        Button bt_anti_shake = findViewById(R.id.bt_anti_shake);

        RxView.clicks(bt_anti_shake)
                .throttleFirst(2000, TimeUnit.MILLISECONDS) // 2秒钟之内 响应你一次

                // 我只给下面 切换 异步
                .observeOn(Schedulers.io())
                .flatMap(new Function<Object, ObservableSource<ProjectBean>>() {
                    @Override
                    public ObservableSource<ProjectBean> apply(Object o) throws Exception {
                        return api.getProject(); // 主数据
                    }
                })

                // 第一步不能map 因为  api Observbale<Bean>  TODO 小作业 同学们自己尝试
                /*.map(new Function<Object, ObservableSource<ProjectBean>>() {
                    @Override
                    public ObservableSource<ProjectBean> apply(Object o) throws Exception {
                        return api.getProject(); // 主数据;
                    }
                })*/

                .flatMap(new Function<ProjectBean, ObservableSource<ProjectBean.DataBean>>() {
                    @Override
                    public ObservableSource<ProjectBean.DataBean> apply(ProjectBean projectBean) throws Exception {
                        return Observable.fromIterable(projectBean.getData()); // 我自己搞一个发射器 发多次 10
                    }
                })
                .flatMap(new Function<ProjectBean.DataBean, ObservableSource<ProjectItem>>() {
                    @Override
                    public ObservableSource<ProjectItem> apply(ProjectBean.DataBean dataBean) throws Exception {
                        return api.getProjectItem(1, dataBean.getId());
                    }
                })

                .observeOn(AndroidSchedulers.mainThread()) // 给下面切换 主线程
                .subscribe(new Consumer<ProjectItem>() {
                    @Override
                    public void accept(ProjectItem projectItem) throws Exception {
                        // 如果我要更新UI  会报错2  不会报错1
                        Log.d(TAG, "accept: " + projectItem);
                    }
                });
    }

doOnNext运用

频繁切换异步线程和UI线程

核心:doOnNext 返回的是obserable,可以继续做事情

需求

  1. 请求服务器注册操作
  2. 注册完成之后,更新注册UI
  3. 马上去登录服务器操作
  4. 登录完成之后,更新登录的UI
/**
 * TODO
 *  Retrofit + RxJava
 * wy.RxJava配合Retrofit。
 * RxJava + Retrofit (请求网络OkHttp  ---- Retorfit  --- Observable)
 *
 * 1.OkHttp 请求网络 (Retorfit)
 * 2.Retorfit 返回一个结果 (Retorfit) --- Observable
 * 3.最终的结果 是RxJava中的 被观察者 上游 Observable
 * 4.一行代码写完需求流程: 从上往下
 *    1.请求服务器,执行注册操作(耗时)切换异步线程
 *    2.更新注册后的所有 注册相关UI - main  切换主线程
 *    3.请求服务器,执行登录操作(耗时)切换异步线程
 *    4.更新登录后的所有 登录相关UI - main  切换主线程
 *
 * 5.看RxJava另外一种的执行流程
 *   初始点 开始点 订阅
 *   1.onSubscribe
 *   2.registerAction(new RegisterRequest())
 *   3..doOnNext 更新注册后的 所有UI
 *   4.flatMap执行登录的耗时操作
 *   5.订阅的观察者 下游 onNext 方法,更新所有登录后的UI
 *   6.progressDialog.dismiss()
 */
public class RequestActivity extends AppCompatActivity {

    private final String TAG = RequestActivity.class.getSimpleName();

    private TextView tv_register_ui;
    private TextView tv_login_ui;

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

        tv_register_ui = findViewById(R.id.tv_login_ui);
        tv_login_ui = findViewById(R.id.tv_login_ui);

    }

    // TODO 方式一 分开写
    @SuppressLint("CheckResult")
    public void request(View view) {
        // 1.请求服务器注册操作
        // 2.注册完成之后,更新注册UI
        MyRetrofit.createRetrofit().create(IReqeustNetwor.class)
                .registerAction(new RegisterRequest())
                .compose(DownloadActivity.rxud())
                .subscribe(new Consumer<RegisterResponse>() {
                    @Override
                    public void accept(RegisterResponse registerResponse) throws Exception {
                        // 更新注册相关的所有UI
                        // .....
                    }
                });

        // 分开写

        // 3.马上去登录服务器操作
        // 4.登录完成之后,更新登录的UI
        MyRetrofit.createRetrofit().create(IReqeustNetwor.class)
                .loginAction(new LoginReqeust())
                .compose(DownloadActivity.rxud())
                .subscribe(new Consumer<LoginResponse>() {
                    @Override
                    public void accept(LoginResponse loginResponse) throws Exception {
                        // 更新登录相关的所有UI
                        // .....
                    }
                });
    }


    /**
     * TODO ================= 下面是一行代码完成整个需求
     */

    private ProgressDialog progressDialog;
    Disposable disposable;

    public void request2(View view) {

        /**
         * 一行代码 实现需求
         * 需求:
         *   还有弹出加载
         *  * 1.请求服务器注册操作
         *  * 2.注册完成之后,更新注册UI
         *  * 3.马上去登录服务器操作
         *  * 4.登录完成之后,更新登录的UI
         */
        MyRetrofit.createRetrofit().create(IReqeustNetwor.class)
                .registerAction(new RegisterRequest()) // todo 1.请求服务器注册操作   // todo 2
                .subscribeOn(Schedulers.io()) // 给上面 异步
                .observeOn(AndroidSchedulers.mainThread()) // 给下面分配主线程
                .doOnNext(new Consumer<RegisterResponse>() { // todo 3,返回的是obserable,可以继续做事情
                    @Override
                    public void accept(RegisterResponse registerResponse) throws Exception {
                        // todo 2.注册完成之后,更新注册UI
                    }
                })
                // todo 3.马上去登录服务器操作
                .observeOn(Schedulers.io()) // 给下面分配了异步线程
                .flatMap(new Function<RegisterResponse, ObservableSource<LoginResponse>>() { // todo 4
                    @Override
                    public ObservableSource<LoginResponse> apply(RegisterResponse registerResponse) throws Exception {
                        Observable<LoginResponse> loginResponseObservable = MyRetrofit.createRetrofit().create(IReqeustNetwor.class)
                                .loginAction(new LoginReqeust());
                        return loginResponseObservable;
                    }
                })
                .observeOn(AndroidSchedulers.mainThread()) // 给下面 执行主线程
                .subscribe(new Observer<LoginResponse>() {

                    // 一定是主线程,为什么,因为 subscribe 马上调用onSubscribe
                    @Override
                    public void onSubscribe(Disposable d) {
                        // TODO 1
                        progressDialog = new ProgressDialog(RequestActivity.this);
                        progressDialog.show();

                        // UI 操作

                        disposable = d;
                    }

                    @Override
                    public void onNext(LoginResponse loginResponse) { // todo 5
                        // TODO 4.登录完成之后,更新登录的UI
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    // todo 6
                    @Override
                    public void onComplete() {
                        // 杀青了
                        if (progressDialog != null) {
                            progressDialog.dismiss();
                        }
                    }
                });

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 必须这样写,最起码的标准
        if (disposable != null)
            if (!disposable.isDisposed())
                disposable.dispose();
    }
}

2.RxJava模式与原理

标准观察者

// 被观察者 实现
public class WechatServerObservable implements Observable {

    // 容器 存储 多个  观察者
    private List<Observer> observers = new ArrayList<>();
    private String message;

    @Override
    public void addObserver(Observer observer) {
        observers.add(observer);
    }

    @Override
    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }

    @Override
    public void notifyObservers() {
        // 遍历容器
        for (Observer observer : observers) {
            observer.update(message);
        }
    }

    @Override
    public void pushMessage(String message) {
        this.message = message;
        // System.out.println("微信服务号更新了消息:" + message);

        // 通知所有 关注了 此服务号的 用户
        notifyObservers();
    }
}

RxJava Hook 点

RxJava 1.x
@NonNull
public static <T> Observable<T> onAssembly(@NonNull Observable<T> source) {
    // 提前预留 给 2.x
    return source;
}

RxJava 2.x
@NonNull
public static <T> Observable<T> onAssembly(@NonNull Observable<T> source) {
    默认情况下,f == null  onObservableAssembly
    Function<? super Observable, ? extends Observable> f = onObservableAssembly;
    if (f != null) {
        return apply(f, source);
    }
    return source;
}

结论:很多很多操作符 都会经过 【onAssembly监听】

map变换操作符原理

public class SourceActivity1 extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //
        // 我想用了多少给 Map操作   flatMap
        // Hook之前的监听
        RxJavaPlugins.setOnObservableAssembly(new Function<Observable, Observable>() {
            @Override
            public Observable apply(Observable observable) throws Exception {
                Log.d(Flag.TAG, "apply: 整个项目 全局 监听 到底有多少地方使用 RxJava:" + observable);

                // 伪代码
                /*if (observable  === ObservableMap)
                    return null;*/

                return null; // 不破坏人家的功能
            }
        });

        testHook();
    }

    /**
     * TODO RxJava Hook 点
     */
    public static void testHook() {
        Observable.create(new ObservableOnSubscribe<Object>() {
            @Override
            public void subscribe(ObservableEmitter<Object> e) throws Exception {
                e.onNext("A");
            }
        })

                // null.map
        .map(new Function<Object, Boolean>() {
            @Override
            public Boolean apply(Object o) throws Exception {
                return true;
            }
        })

        .subscribe(new Consumer<Boolean>() {
            @Override
            public void accept(Boolean aBoolean) throws Exception {

            }
        })   ;
    }
}

RxJava的观察者模式

创建Observer

/**
 * TODO RxJava的观察者模式
 * 1:Observer 源码看看
 * 2:Observable创建过程 源码分析
 * 3:subscribe订阅过程 源码分析
 */
public class SourceActivity2 extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // 结论: new ObservableCreate() {source == 自定义source}
        // 2:Observable创建过程 源码分析
        Observable.create(

                // 自定义source
                new ObservableOnSubscribe<String>() {
                    @Override
                    public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                        // 发射器.onNext
                        emitter.onNext("A");
                    }
        })

        // 3:subscribe订阅过程 源码分析
        // ObservableCreate. subscribe
        .subscribe(
                
                // 自定义观察者
                // 1:Observer 源码看看
                new Observer<String>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(String s) {

                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }
}

创建Observable

Observable创建过程时 重要的点记录:

Observable创建过程时序图如下:

使用subcribe()订阅

Observable 与 Observer 订阅的过程 重要的点记录:

Observable 与 Observer 订阅的过程 重要步骤:

Observable 与 Observer 订阅的过程时序图如下:

标准观察者模式 与 RxJava观察者模式对比

从模式角度分析 标准观察者模式 与 RxJava观察者模式

Map变换操作符原理

Map源码分析

public class SourceActivity3 extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // ObseravbleCreate  自定义source传递进去了 == source
        Observable.create(
                // 自定义source
                new ObservableOnSubscribe<String>() {
                    @Override
                    public void subscribe(ObservableEmitter<String> e) throws Exception {

                    }
        })
         //  ObseravbleCreate.map
        .map(new Function<String, Bitmap>() {
            @Override
            public Bitmap apply(String s) throws Exception {
                return null;
            }
        })
        // ObservableMap.subscribe
        .subscribe(

                // 自定义观察者(终点)
                new Observer<Bitmap>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Bitmap bitmap) {

                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }

}

一个Map源码分析

RxJava装饰模型

Map的装饰模型

public class SourceActivity4 extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> e) throws Exception {
                e.onNext("Derry");
                e.onComplete();
            }
        })

        // ↓ObservableCreate.map   包裹模型中 最里面
        .map(new Function<String, Integer>() {
            @Override
            public Integer apply(String s) throws Exception {
                return 45454;
            }
        })

        // ObservableMap.map
        .map(new Function<Integer, Boolean>() {
            @Override
            public Boolean apply(Integer integer) throws Exception {
                return true;
            }
        })

        // ↓包裹模型中最外面   往上走↑的时候在一层 层的剥开
        // ObservableMap.subscribe
        .subscribe(new Observer<Boolean>() {
            @Override
            public void onSubscribe(Disposable d) { }

            @Override
            public void onNext(Boolean bool) {
                Log.d(Flag.TAG, "onNext bool:" + bool);
            }

            @Override
            public void onError(Throwable e) { }

            @Override
            public void onComplete() { }
        });
    }
}

背压:我生产的速度快过你消费的速度

private void t() {

        // 自己去查询
       // Flowable.create

       // single(只能发射单个) Observable的简化版    Observable完整版(多个 单个)

       // 背压
       Observable.create(new ObservableOnSubscribe<String>() {
           @Override
           public void subscribe(ObservableEmitter<String> e) throws Exception {
               while (true) {   //不停的发送
                   e.onNext("A");
               }
           }
       })

       .subscribe(new Observer<String>() {
           @Override
           public void onSubscribe(Disposable d) {

           }

           @Override
           public void onNext(String s) {
               // Thread.sleep(5000); // 五秒后 消费下
           }

           @Override
           public void onError(Throwable e) {

           }

           @Override
           public void onComplete() {

           }
       });
   }

3.RxJava原理

### 线程切换原理

在Android中RxJava和RxAndroid两个要一起用

// 依赖RxAndroid 2X 的依赖库
// 增加RxJava 2X 的依赖库
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
implementation 'io.reactivex.rxjava2:rxjava:2.0.7'
 // RxAndroid有什么用
    private void test00() {
        Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> e) throws Exception {
                e.onNext("A");
            }
        })
        .observeOn(Schedulers.io()) // rxjava
        .subscribeOn(AndroidSchedulers.mainThread()) // rxandroid
        .subscribe(new Consumer<String>() {
            @Override
            public void accept(String s) throws Exception {

            }
        })
        ;
    }
private Disposable disposable;

private void test01() {
        Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> e) throws Exception {}
        }).subscribe(new Observer<String>() {
            @Override
            public void onSubscribe(Disposable d) {
                disposable = d;
            }

            @Override
            public void onNext(String s) {}

            @Override
            public void onError(Throwable e) {}

            @Override
            public void onComplete() {}
        });


        // ---

        Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> e) throws Exception {}
        }).subscribe(new Consumer<String>() {
            @Override
            public void accept(String s) throws Exception {}
        });
    }

    // 处理报黄
    private void test02() {

        disposable = Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> e) throws Exception {
                e.onNext("Derry");
                e.onNext("A");
                e.onComplete();
            }
        }).subscribe(new Consumer<String>() {
            @Override
            public void accept(String s) throws Exception {

            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        // 最起码的写法
        if (disposable != null)
            if (!disposable.isDisposed())
                disposable.dispose();
    }

subscribeOn() 源码分析

subscribeOn 给上面代码分配线程

public class RxJavaThreadSource1 extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // TODO Hook  IO 传递进去的Hook
        RxJavaPlugins.setIoSchedulerHandler(new Function<Scheduler, Scheduler>() {
            @Override
            public Scheduler apply(Scheduler scheduler) throws Exception {
                Log.d(L.TAG, "apply: 全局 监听 scheduler:" +scheduler);
                return scheduler;
            }
        });

        // TODO hook 给 IO 初始化
        RxJavaPlugins.setInitIoSchedulerHandler(new Function<Callable<Scheduler>, Scheduler>() {
            @Override
            public Scheduler apply(Callable<Scheduler> schedulerCallable) throws Exception {
                Log.d(L.TAG, "apply: 全局 监听 init scheduler:" +schedulerCallable.call());
                return schedulerCallable.call();
            }
        });


        Observable.create(
                // 自定义source
                new ObservableOnSubscribe<String>() {
                    @Override
                    public void subscribe(ObservableEmitter<String> e) throws Exception {
                        e.onNext("Derry");

                        Log.d(L.TAG, "自定义source: " + Thread.currentThread().getName());
                    }
        })
        // ObservbaleCreate.subscribeOn
        // TODO 第二步     new IOScheduler ---> 线程池 传递进去
        .subscribeOn(
                // TODO 第一步  到底干了什么 ( new IOScheduler ---> 线程池)
                Schedulers.io() // 耗时读取的异步
                // Schedulers.newThread() // 开启新线程
        )

         // A线程. subscribe
         //  ObservableSubscribeOn.subscribe
        .subscribe(
                // 终点
                new Observer<String>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                        Disposable disposable = d;
                        Log.d(L.TAG, "onSubscribe: " +  Thread.currentThread().getName());
                    }

                    @Override
                    public void onNext(String s) {
                        Log.d(L.TAG, "onNext: " + Thread.currentThread().getName());
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
        });
    }
}

observeOn

observeOn 给下面代码分配线程

public class RxJavaThreadSource2 extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        new Thread(){

            @Override
            public void run() {
                super.run();

                test();
            }
        }.start();

    }

    private void test() {
        Observable.create(

                // 自定义source
                new ObservableOnSubscribe<String>() {
                    @Override
                    public void subscribe(ObservableEmitter<String> e) throws Exception {
                        e.onNext("Derry");

                        Log.d(L.TAG, "自定义source: " + Thread.currentThread().getName());
                    }
                })

                // TODO 第二步骤
                .observeOn(

                        // TODO 第一步   主线程的 Handlnr
                        AndroidSchedulers.mainThread()

                )

                // subsceOn(1)  // 会显示是这个线程的原因,上一层卡片是被1线程执行
                // subsceOn(2)
                // subsceOn(3)

                // observeOn(A)
                // observeOn(B)
                // observeOn(C) // 终点是被C执行


                // ObservableObserveOn.subscribe
                .subscribe(

                        // 终点
                        new Observer<String>() {
                            @Override
                            public void onSubscribe(Disposable d) {
                                Log.d(L.TAG, "onSubscribe: " +  Thread.currentThread().getName());
                            }

                            @Override
                            public void onNext(String s) {
                                Log.d(L.TAG, "onNext: " + Thread.currentThread().getName());
                            }

                            @Override
                            public void onError(Throwable e) {

                            }

                            @Override
                            public void onComplete() {

                            }
                        });
    }


    private void t() {
        new Handler(Looper.getMainLooper()) {
            @Override
            public void handleMessage(@NonNull Message msg) {
                super.handleMessage(msg);

                // UI 操作 ...
            }
        };


        new Thread(){
            @Override
            public void run() {
                super.run();

                new Handler(Looper.getMainLooper()) {
                    @Override
                    public void handleMessage(@NonNull Message msg) {
                        super.handleMessage(msg);

                        // UI 操作 ...  百分之百 Ui线程 没有问题
                    }
                };
            }
        }.start();


       new Handler(new Handler.Callback() {
           @Override
           public boolean handleMessage(@NonNull Message msg) {
               return false;
           }
       });
    }
}

Schedulers的分类

调度器类型效果
Schedulers.computation()用于计算任务,如事件循环或和回调处理,不要用于IO操作(IO操作请使用Schedulers.io());默认线程数等于处理器的数量
Schedulers.from(executor)使用指定的Executor作为调度器
Schedulers.immediate( )在当前线程立即开始执行任务
Schedulers.io( )用于IO密集型任务
Schedulers.newThread( )为每个任务创建一个新线程
Schedulers.trampoline( )当其它排队的任务完成后,在当前线程排队开始执行
AndroidSchedulers.mainThread()用于Android的UI更新操作

4.自定义RxView操作符

ViewClickObservable

public class ViewClickObservable extends Observable<Object> {

    private final View view;

    // 事件  第一节课 防抖 事件 没用
    private static final Object EVENT = new Object();
    private static Object EVENT2;

    public ViewClickObservable(View view) {
        this.view = view;

        EVENT2 = view;
    }

    @Override
    protected void subscribeActual(Observer<? super Object> observer) {
        // 可以干自己的

        MyListener myListener = new MyListener(view, observer);
        observer.onSubscribe(myListener);

        this.view.setOnClickListener(myListener);
    }

    // 我们的包裹
    static final class MyListener implements View.OnClickListener, Disposable {

        private final View view;
        private Observer<Object> observer;  // 存一份 下一层

        // 原子性,同学们自行看看文章
        // https://www.jianshu.com/p/8a44d4a819bc
        // boolean  == AtomicBoolean
        private final AtomicBoolean isDisposable = new AtomicBoolean();

        public MyListener(View view, Observer<Object> observer) {
            this.view = view;
            this.observer = observer;


        }

        @Override
        public void onClick(View v) {
            if (isDisposed() == false) {
                observer.onNext(EVENT);
            }

        }

        // 如果用调用了 中断
        @Override
        public void dispose() {
            // 如果没有中断过,才有资格,   取消view.setOnClickListener(null);
            if (isDisposable.compareAndSet(false, true)) {
                // 主线程 很好的中断
                if (Looper.myLooper() == Looper.getMainLooper()) {
                    view.setOnClickListener(null);

                } else { // 主线程,通过Handler的切换
                    /*new Handler(Looper.getMainLooper()) {
                        @Override
                        public void handleMessage(@NonNull Message msg) {
                            super.handleMessage(msg);
                            view.setOnClickListener(null);
                        
                    };*/

                    // HandlerScheduler.scheduleDirect

                    AndroidSchedulers.mainThread().scheduleDirect(new Runnable() {
                        @Override
                        public void run() {
                            view.setOnClickListener(null);
                        }
                    });
                }
            }
        }

        @Override
        public boolean isDisposed() {
            return isDisposable.get();
        }
    }
}

RxView

public class RxView {

    private final static String TAG = RxView.class.getSimpleName();

    // 我们自己的操作符 == 函数
    public static Observable<Object> clicks(View view) {
        return new ViewClickObservable(view);
    }


}
public class RxActivity extends AppCompatActivity {

    @SuppressLint("CheckResult")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_rx);

        // 给这个控件做防抖
        Button button = findViewById(R.id.button);

        RxView.clicks(button)
                .throttleFirst(2000, TimeUnit.MILLISECONDS)
                .subscribe(new Consumer<Object>() {
                    @Override
                    public void accept(Object o) throws Exception {
                        Observable.create(new ObservableOnSubscribe<String>() {
                            @Override
                            public void subscribe(ObservableEmitter<String> e) throws Exception {
                                e.onNext("Derry");
                            }
                        })
                        .subscribe(new Consumer<String>() {
                            @Override
                            public void accept(String s) throws Exception {
                                Log.d(L.TAG, "accept: 终点:" + s);
                            }
                        });
                    }
                });
    }
}