Android RxJava源码分析

前言

1.此处主要是基于RxJava2.0的解析

2.讲解内容包括 基本介绍 原理 具体使用


一、定义

  • RxJava在GitHub中的介绍:

https://github.com/ReactiveX/RxJava/wiki

//RxJava主页地址:https://github.com/ReactiveX/RxJava/wiki

RxJava is a Java VM implementation of ReactiveX (Reactive Extensions): a library for composing asynchronous and event-based programs by using observable sequences.
// 翻译:RxJava 是ReactiveX (Reactive Extensions)在JavaVM上使用Observable序列组合异步和基于事件的程序的库。

RxJava is Lightweight
RxJava tries to be very lightweight. It is implemented as a single JAR that is focused on just the Observable abstraction and related higher-order functions.
// 翻译:RxJava尽力做到非常轻巧。它仅关注Observable的抽象和与之相关的高层函数,实现为一个单独的JAR文件。
  • 总结:RxJava 是一个 基于事件流、实现异步操作 的库


二、作用

  • 主要用于异步操作的实现

Android中实现异步的方式:
Java方法来实现异步:
    1、继承Thread类
    2、实现Runnable接口
Android 的方法实现异步:
    1、Handler
    2、AsyncTask
    3、RxJava
用Java方法来实现异步:

主要有两种方法来实现异步,继承Thread类和实现Runnable接口

1、继承Thread类
    private void asynThread() {
        AsynThread asynThread = new AsynThread("asynThread");
        asynThread.start();
    }
    
    public class AsynThread extends Thread {
        private String name;
        public AsynThread(String name) {
            this.name = name;
        }
    
        @Override
        public void run() {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    //ui更新
                    tv_content.setText(name);
                }
            });
        }
    }
2、实现Runnable接口
    private void asynThreadRunable() {
        AsynThreadRunable asynThreadRunable = new AsynThreadRunable("asynThreadRunable");
        Thread thread = new Thread(asynThreadRunable);
        thread.start();
    }

    public class AsynThreadRunable implements Runnable{
        private String name;
        public AsynThreadRunable(String name) {
            this.name = name;
        }

        @Override
        public void run() {
            Log.d("AsynThreadRunable",name);
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    //ui更新
                    tv_content.setText(name);
                }
            });
        }
    }

    private void asynThreadRunableInner(){
        //或者直接使用内部类:
        new Thread(new Runnable(){
            @Override
            public void run(){
                Log.d("asynThreadRunableInner","执行耗时或者异步操作:");
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        //ui更新
                        tv_content.setText("asynThreadRunableInner");
                    }
                });
            }
        }).start();
    }
Android的方法实现异步:
1、Handler

Handler 用来解决线程间通信,可以在子线程中提醒UI线程更新组件

    private void aysnHandler(){
        new Thread(new Runnable(){
            @Override
            public void run() {
                //在子线程中执行耗时任务,执行完毕后需要通过 Handler 通知UI线程更新UI
                mHandler.sendEmptyMessage(0);
            }

        }).start();
    }

    Handler mHandler = new Handler(){
        @Override
        public void handleMessage(Message mas){
            switch(mas.what){
                case 0:
                    //此处进行UI的更新
                    tv_content.setText("aysnHandler");
                    break;
            }
        }
    };

主线程也可以给子线程发消息:

    private void aysnMyHandler(){
        final MyThread myThread = new MyThread();
        myThread.start();
        //发消息到目标子线程
        tv_content.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                myThread.mMyHandler.obtainMessage(0).sendToTarget();
            }
        });


    }

    public class MyThread extends Thread{
        public  Handler mMyHandler;
        @Override
        public void run() {
            super.run();
            //1.建立消息循环,初始化Looper
            Looper.prepare();
            mMyHandler = new Handler(){
                @Override
                public void handleMessage(Message msg) {
                    super.handleMessage(msg);
                    int what = msg.what;
                    if(what == 0){
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                tv_content.setText("发消息到目标子线程");
                            }
                        });

                    }
                }
            };
            //启动消息循环
            Looper.loop();
        }
    }
2、AsyncTask

使用AsyncTask来实现异步简单便携,各个过程都有明确的回调,过程可控,但是缺点就是要是执行多个异步,就会变得很复杂

    private void asynAsynTask(){
        MyAsyncTask myAsyncTask = new MyAsyncTask();
        myAsyncTask.execute("http://www.baidu.com/xxx.jpg");
    }

    class MyAsyncTask extends AsyncTask<String, Integer,String> {

        @Override
        protected void onPreExecute() {
            //这里是开始线程之前执行的,是在UI线程
            super.onPreExecute();
        }

        @Override
        protected String doInBackground(String... params){
            //这是在后台子线程中执行的
            String url = params[0];
            return url;
        }
        @Override
        protected void onCancelled(){
            //当任务被取消时回调
            super.onCancelled();
        }
        @Override
        protected void onProgressUpdate(Integer... values){
            super.onProgressUpdate(values);
            //更新进度
        }
        @Override
        protected void onPostExecute(String url){
            super.onPostExecute(url);
            //当任务执行完成时调用,在UI线程
            tv_content.setText(url);
        }
    }
3、RxJava
    private void aysnRxJava(){
        Observable.create(new ObservableOnSubscribe<Integer>() {
            // 1. 创建被观察者 & 生产事件
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                emitter.onNext(1);
                emitter.onNext(2);
                emitter.onNext(3);
                emitter.onComplete();
            }
        }).subscribe(new Observer<Integer>() {
            // 2. 通过通过订阅(subscribe)连接观察者和被观察者
            // 3. 创建观察者 & 定义响应事件的行为
            @Override
            public void onSubscribe(Disposable d) {
                Log.d("TAG", "开始采用subscribe连接");
            }
            // 默认最先调用复写的 onSubscribe()

            @Override
            public void onNext(Integer value) {
                Log.d("TAG", "对Next事件"+ value +"作出响应"  );
            }

            @Override
            public void onError(Throwable e) {
                Log.d("TAG", "对Error事件作出响应");
            }

            @Override
            public void onComplete() {
                Log.d("TAG", "对Complete事件作出响应");
            }

        });
    }

三、特点

3.1、 Handler异步实现的原理和使用的优缺点

在Handler 异步实现时,涉及到 Handler, Looper, Message,Thread四个对象,实现异步的流程是主线程启动Thread(子线程)àthread(子线程)运行并生成Message- àLooper获取Message并传递给HandleràHandler逐个获取Looper中的Message,并进行UI变更。

使用的优点:

结构清晰,功能定义明确

对于多个后台任务时,简单,清晰

3.2、AsyncTask实现的原理,和适用的优缺点

AsyncTask,是android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度(可以通过接口实现UI进度更新),最后反馈执行的结果给UI主线程.

使用的优点:

简单,快捷

过程可控

使用的缺点:

在使用多个异步操作和并需要进行Ui变更时,就变得复杂起来.

3.3、RxJava特点

RxJava的使用方式是:基于事件流的链式调用,所以使得 RxJava:

逻辑简洁

实现优雅

使用简单

更重要的是,随着程序逻辑的复杂性提高,仍然能够保持简洁,优雅,兼顾了Handler和AsyncTask所有优点

四、原理

从上段RxJava代码的实现上可以总结出如下执行示意图:

RxJava可以看做是一种扩展的观察者模式

RxJava的扩展观察者模式中有4个角色:

角色作用
被观察者(Observable)产生事件
观察者(Observer)接收事件,并给出响应动作
订阅(Subscribe)连接 被观察者 & 观察者
事件(Event)被观察者 & 观察者 沟通的载体

总结:

被观察者 (Observable) 通过 订阅(Subscribe) 按顺序发送事件给观察者(Observer), 观察者(Observer) 按顺序接收事件 & 作出对应的响应动作

五、源码分析

    private void aysnRxJava(){
        Observable.create(new ObservableOnSubscribe<Integer>() {
            // 1. 创建被观察者 & 生产事件
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                emitter.onNext(1);
                emitter.onNext(2);
                emitter.onNext(3);
                emitter.onComplete();
            }
        }).subscribe(new Observer<Integer>() {
            // 2. 通过通过订阅(subscribe)连接观察者和被观察者
            // 3. 创建观察者 & 定义响应事件的行为
            @Override
            public void onSubscribe(Disposable d) {
                Log.d("TAG", "开始采用subscribe连接");
            }
            // 默认最先调用复写的 onSubscribe()

            @Override
            public void onNext(Integer value) {
                Log.d("TAG", "对Next事件"+ value +"作出响应"  );
            }

            @Override
            public void onError(Throwable e) {
                Log.d("TAG", "对Error事件作出响应");
            }

            @Override
            public void onComplete() {
                Log.d("TAG", "对Complete事件作出响应");
            }

        });
    }

结合上面代码和使用步骤带着问题一起来了解下RxJava运行的流程:

Rxjava如何创建事件源、发射事件、何时发射事件、如何将观察者和被观察者关联起来

1、Observable

Observable是事件生产者,定义需发送的事件

a、首先来分析事件是如何生成的,直接看代码 Observable.create()方法。

    @CheckReturnValue
    @NonNull
    @SchedulerSupport(SchedulerSupport.NONE)
    //方法中传入的 ObservableOnSubscribe是个接口,只包含subscribe方法,这里就是事件生产的源头。
    public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
        //判空操作
        ObjectHelper.requireNonNull(source, "source is null");
        //这里是重头戏,return了说明这里生产了Observable
        return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
    }

RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));return了说明这里生产了Observable的。继续跟踪进去

    /**
     * Calls the associated hook function.
     * @param <T> the value type
     * @param source the hook's input value
     * @return the value returned by the hook
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    @NonNull
    public static <T> Observable<T> onAssembly(@NonNull Observable<T> source) {
        Function<? super Observable, ? extends Observable> f = onObservableAssembly;
        if (f != null) {
            return apply(f, source);
        }
        return source;
    }

根据注释可以看出该方法是hook function 称为钩子函数,分析代码中静态对象onObservableAssembly默认为null, 所以此方法直接返回传入的参数source。

onObservableAssembly可以通过静态方法RxJavaPlugins. setOnObservableAssembly ()设置全局的Hook函数

//提取与onObservableAssembly有关的代码
public final class RxJavaPlugins {

    @SuppressWarnings("rawtypes")
    @Nullable
    static volatile Function<? super Observable, ? extends Observable> onObservableAssembly;
    
    //set方法
    public static void setOnObservableAssembly(@Nullable Function<? super Observable, ? extends Observable> onObservableAssembly) {
        if (lockdown) {
            throw new IllegalStateException("Plugins can't be changed anymore");
        }
        RxJavaPlugins.onObservableAssembly = onObservableAssembly;
    }
    
    //get方法
    public static Function<? super Observable, ? extends Observable> getOnObservableAssembly() {
        return onObservableAssembly;
    }
    
    //方法的使用入口
    public static <T> Observable<T> onAssembly(@NonNull Observable<T> source) {
        Function<? super Observable, ? extends Observable> f = onObservableAssembly;
        if (f != null) {
            return apply(f, source);
        }
        return source;
    }
}

至此我们明白了,事件的源就是new ObservableCreate()对象,将ObservableOnSubscribe作为参数传递给ObservableCreate的构造函数。事件是由接口ObservableOnSubscribe的subscribe方法上产的,至于何时生产事件,我们继续分析。

b、Observable是何时生产事件的,进入ObservableCreate分析

    /**
        * 源码分析:Observable.create(new ObservableOnSubscribe<Integer>(){...})
    **/
    public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {

    ...
      // 仅贴出关键源码,根据上面分析这里return相当于下面代码

      return new ObservableCreate<T>(source);
      // 创建ObservableCreate类对象 ->>分析1
      // 注:传入source对象(即 我们手动创建的ObservableOnSubscribe对象)
    }
    
    /**
      * 分析1:new ObservableCreate<T>(source)
      * 这里只贴出部分需要分析的代码
    **/
    // 通过extends Observable得知ObservableCreate类 就是 Observable的子类
    public final class ObservableCreate<T> extends Observable<T> {
    final ObservableOnSubscribe<T> source;

    // 构造函数
     // 传入了传入source对象 = 我们手动创建的ObservableOnSubscribe对象
    public ObservableCreate(ObservableOnSubscribe<T> source) {
        this.source = source;
    }
    
    /**
      *重写了subscribeActual方法
      *跟踪进去发现该方法是Observable执行subscribe订阅时执行的方法,所以只有执行subscribe时才会触发;
      *得出结论:Observable是何时生产事件的,就是在Observable执行subscribe订阅时触发的
      *
    **/
    @Override
    protected void subscribeActual(Observer<? super T> observer) {
        // 1. 创建1个CreateEmitter对象(封装成1个Disposable对象)
        // 作用:发射事件
        CreateEmitter<T> parent = new CreateEmitter<T>(observer);
        
        // 2. 调用观察者(Observer)的onSubscribe()
        // onSubscribe()的实现 = 使用步骤的第2步(创建观察者(Observer))时复写的onSubscribe()
        observer.onSubscribe(parent);

        try {
            // 3. 调用source对象的subscribe()
            // source对象 = 使用步骤1(创建被观察者(Observable))中创建的ObservableOnSubscribe对象 
            // subscribe()的实现 = 使用步骤1(创建被观察者(Observable))中复写的subscribe()
            source.subscribe(parent);
        } catch (Throwable ex) {
            Exceptions.throwIfFatal(ex);
            parent.onError(ex);
        }
    }
    // onNext()源码分析
    static final class CreateEmitter<T>
    extends AtomicReference<Disposable>
    implements ObservableEmitter<T>, Disposable {

        private static final long serialVersionUID = -3434801548987643227L;

        final Observer<? super T> observer;

        CreateEmitter(Observer<? super T> observer) {
            this.observer = observer;
        }

        @Override
        public void onNext(T t) {
            // 注:发送的事件不可为空
            if (t == null) {
                onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources."));
                return;
            }
            / 若无断开连接(调用Disposable.dispose()),则调用观察者(Observer)的同名方法 = onNext()
            // 观察者的onNext()的内容 = 使用步骤2中复写内容
            if (!isDisposed()) {
                observer.onNext(t);
            }
        }

        // onError()、onComplete()类似
        // 特别说明:调用这两个方法,最终都会自动调用dispose(),即断开观察者 & 被观察者的连接,看finally
        @Override
        public void onError(Throwable t) {
            if (!tryOnError(t)) {
                RxJavaPlugins.onError(t);
            }
        }

        @Override
        public boolean tryOnError(Throwable t) {
            if (t == null) {
                t = new NullPointerException("onError called with null. Null values are generally not allowed in 2.x operators and sources.");
            }
            if (!isDisposed()) {
                try {
                    observer.onError(t);
                } finally {
                    dispose();
                }
                return true;
            }
            return false;
        }

        @Override
        public void onComplete() {
            if (!isDisposed()) {
                try {
                    observer.onComplete();
                } finally {
                    dispose();
                }
            }
        }
    }

2、Observer

观察者 & 定义响应事件的行为

看源码得知Observer是个接口,包含如下方法:

public interface Observer<T> {

    // 接口内含4个方法,分别用于 响应 对应于被观察者发送的不同事件

    void onSubscribe(@NonNull Disposable d);

    void onNext(@NonNull T t);

    void onError(@NonNull Throwable e);

    void onComplete();

}

3、subscribe

通过订阅(subscribe)连接观察者和被观察者

源码分析:Observable.subscribe(observer)

/**
  * 源码分析:Observable.subscribe(observer)
  * 说明:该方法属于 Observable 类的方法(注:传入1个 Observer 对象)
  **/  

  @Override
  public final void subscribe(Observer<? super T> observer) {

    ...
    // 贴出关键源码
   
    subscribeActual(observer);
    // 继续往下分析

  }

/**
  * Observable.subscribeActual(observer)
  * 说明:属于抽象方法,由子类实现;此处的子类 = 步骤1创建被观察者(Observable)时创建的ObservableCreate类
  * 即 在订阅时,实际上是调用了使用步骤1中创建被观察者(Observable)时创建的ObservableCreate类里的subscribeActual()
  *
  **/
  protected abstract void subscribeActual(Observer<? super T> observer);

4、总结

Rxjava的流程是:

  •  1、Observable.create 创建事件源,但并不生产也不发射事件。

  •  2、实现observer接口,但此时没有也无法接受到任何发射来的事件。

  •  3、订阅 observable.subscribe(observer), 此时会调用具体Observable的实现类中的subscribeActual方法, 此时会才会真正触发事件源生产事件,事件源生产出来的事件通过Emitter的onNext,onError,onComplete发射给observer对应的方法由下游observer消费掉。从而完成整个事件流的处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值