RxJava源码(衍生RxBinding)

RxJava源码(从 just 开始)

RxJava源码(简单操作符)

RxJava源码(线程)

RxJava源码(背压)

RxJava源码(RxBinding)

RxJava源码(衍生 RxLifecycle)

RxBinding 源码路径,这边直接实战进入源码。

        val subscribe = button.clicks()
                .subscribe {
                    Toast.makeText(this@RxbindingActivity, "RxbindingActivity", Toast.LENGTH_LONG).show()
                }

这是一段 kotlin 代码,button 是在布局中的一个按钮。通过这段代码就可以监听 button 的点击事件。怎么做到的呢?

@CheckResult
fun View.clicks(): Observable<Unit> {
    return ViewClickObservable(this)
}

View.clicks() 方法返回 Observable 被观察者,它的方法中创建了 ViewClickObservable。

private class ViewClickObservable(
        private val view: View
) : Observable<Unit>() {
}

ViewClickObservable 的构造方法,只有一个参数 View。它继承自 Observable,和前几节说的 Flowable 一致,它必须实现 subscribeActual,subscribeActual 方法肯定在 ViewClickObservable 订阅的时候运行。

    override fun subscribeActual(observer: Observer<in Unit>) {
        if (!checkMainThread(observer)) {
            return
        }
        val listener = Listener(view, observer)
        observer.onSubscribe(listener)
        view.setOnClickListener(listener)
    }

点击事件不能异步,所以首先检 UI 线程。其次创建 Listener,与传入的 observer 完成订阅。

    private class Listener(
            private val view: View,
            private val observer: Observer<in Unit>
    ) : MainThreadDisposable(), OnClickListener {

        override fun onClick(v: View) {
            if (!isDisposed) {
                observer.onNext(Unit)
            }
        }

        override fun onDispose() {
            view.setOnClickListener(null)
        }
    }

 Listener 中实现了 OnClickListener,实现 onClick,在 onClick 中调用 observer 发射事件。

而继承的另一个 MainThreadDisposable,它其实就是 Disposable,不过实现了 dispose() 函数,下面就是,这里不是流程重点。

        if (unsubscribed.compareAndSet(false, true)) {
            if (Looper.myLooper() == Looper.getMainLooper()) {
                onDispose();
            } else {
                AndroidSchedulers.mainThread().scheduleDirect(new Runnable() {
                    @Override public void run() {
                        onDispose();
                    }
                });
            }
        }

由此我们可以看出 View.clicks() 流程了:

创建 ViewClickObservable 被观察者,在 ViewClickObservable 中创建 Listener 监听 view 的点击事件以便发射。

我们的观察者之后订阅上 ViewClickObservable,时刻接受发射的点击事件。

普通按钮的点击事件很简单。在 java 中我们使用 RxView.onClick() 方法,实则时 kotlin 函数的在java中的用法。

@file:JvmName("RxView")
@file:JvmMultifileClass

以上的这些代码在 ViewClickObservable.kt 文件中,而加上了 @file:JvmName("注解的名字")注解,在 java 中就可以实现 注解的名字 + 直接调用函数。

很简单吧。

我们经常放置重复点击使用 throttleFirst(),它实际是 RxJava 内部的函数,当按钮被点击时,我们需要判断是否与上次点击点击的时间间隔,然后再去响应按钮的点击事件。这里就不所说了。

看看其他的

View.longClicks()

private class ViewLongClickObservable(): Observable<Unit>()

private class Listener(): MainThreadDisposable(), OnLongClickListener

  override fun subscribeActual(observer: Observer<in Unit>) {
    val listener = Listener(view, handled, observer)
    observer.onSubscribe(listener)
    view.setOnLongClickListener(listener)
  }


TextView.textChanges()

fun TextView.textChanges(): InitialValueObservable<CharSequence> {
  return TextViewTextChangesObservable(this)
}
abstract class InitialValueObservable<T> : Observable<T>()

返回的 InitialValueObservable 也是 Observable 对象。

  override fun subscribeListener(observer: Observer<in CharSequence>) {
    val listener = Listener(view, observer)
    observer.onSubscribe(listener)
    view.addTextChangedListener(listener)
  }

addTextChangedListener 监听文字变化。

    override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
      if (!isDisposed) {
        observer.onNext(s)
      }
    }

onTextChanged 中发射。

Rxbinding 相关的操作库基本都是这么实现的,理解了上几篇的RxJava原理,看来离自己写个库也不远了 。

另外,这边总结下常用的 Subject,它既是 Observable,又是 observer 。也就是既可以发送事件,也可以接收事件。

ReplaySubject :无论是在接收到数据前还是数据后订阅,ReplaySubject都会发射所有数据给订阅者。

BehaviorSubject :接受订阅前最后一个数据和订阅后接收到的所有数据。

PublishSubject :仅会向 Observer 释放在订阅之后 Observable 释放的数据。

AsyncSubject :仅释放 Observable 释放的最后一个数据,并且仅在 Observable 完成之后。然而如果当 Observable 因为异常而终止,AsyncSubject 将不会释放任何数据,但是会向 Observer 传递一个异常通知。

SerializedSubject:将 Subject 串行化的方法,所有其他的 Observable 和 Subject 方法都是线程安全的。

UnicastSubject :仅支持订阅一次的 Subject ,如果多个订阅者试图订阅这个 Subject ,若该 subject 未 terminate,将会受到 IllegalStateException ,若已经 terminate,那么只会执行 onError 或者 onComplete 方法。

我们可在自己的程序中创建 Subject,如

    val mUserViewStateSubject: BehaviorSubject<RawMessage> = BehaviorSubject.create()

    //改变才发送数据
    fun observeViewState(): Observable<RawMessage> {
        return mUserViewStateSubject.hide().distinctUntilChanged()
    }

我在 mvvm 架构中,在 ViewModel 中创建出 BehaviorSubject,并且在 Activity 或 Fragment 中调用 observeViewState

        mAiuiViewModel.observeViewState()
            .observeOn(RxSchedulers.ui)
            .autoDisposable(scopeProvider)
            .subscribe(this::onMsgArrived)

在 ViewModel 中数据改变了,通过 mUserViewStateSubject.onNext(xxx) 发射数据。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RxJava中的flatMap操作符是一个非常常用的操作符,它可以将一个Observable发射的事件序列转换成多个Observables,然后将这些Observables发射的事件序列合并后再发射出去。 下面是flatMap操作符的源码解析: ```java public final <R> Observable<R> flatMap(Function<? super T, ? extends ObservableSource<? extends R>> mapper) { ObjectHelper.requireNonNull(mapper, "mapper is null"); return RxJavaPlugins.onAssembly(new ObservableFlatMap<>(this, mapper, false, Integer.MAX_VALUE, bufferSize())); } ``` 可以看到,flatMap操作符的实现是通过创建一个ObservableFlatMap对象来完成的。其中,mapper参数表示将原始Observable发射的事件转换成的新Observable,它是一个Function类型的参数,即接受一个T类型的参数并返回一个ObservableSource类型的结果。 ObservableFlatMap的构造函数如下所示: ```java ObservableFlatMap(ObservableSource<T> source, Function<? super T, ? extends ObservableSource<? extends R>> mapper, boolean delayErrors, int maxConcurrency, int bufferSize) { this.source = source; this.mapper = mapper; this.delayErrors = delayErrors; this.maxConcurrency = maxConcurrency; this.bufferSize = bufferSize; } ``` ObservableFlatMap的核心实现是在subscribeActual方法中完成的: ```java @Override public void subscribeActual(Observer<? super R> observer) { if (ObservableScalarXMap.tryScalarXMapSubscribe(source, observer, mapper)) { return; } source.subscribe(new FlatMapObserver<>(observer, mapper, delayErrors, maxConcurrency, bufferSize)); } ``` 在subscribeActual方法中,首先判断源Observable是否可以直接转换为ObservableScalarXMap,如果可以的话直接进行转换,否则创建一个FlatMapObserver对象并进行订阅。 FlatMapObserver是flatMap的核心实现类,它实现了Observer接口,并且在接收到源Observable发射的事件时,会先将事件转换成新的Observable,然后将新Observable的发射事件序列合并到一个新的Observable中,最后再将新的Observable发射出去。 ```java static final class FlatMapObserver<T, R> extends AtomicInteger implements Observer<T>, Disposable { // ... @Override public void onNext(T t) { ObservableSource<? extends R> o; try { o = ObjectHelper.requireNonNull(mapper.apply(t), "The mapper returned a null ObservableSource"); } catch (Throwable e) { Exceptions.throwIfFatal(e); upstream.dispose(); onError(e); return; } if (cancelled) { return; } if (maxConcurrency != Integer.MAX_VALUE) { synchronized (this) { if (wip == maxConcurrency) { queue.offer(t); return; } wip++; } } o.subscribe(new InnerObserver(inner, delayErrors, this)); } // ... } ``` 在FlatMapObserver的onNext方法中,首先调用mapper将源Observable发射的事件转换成新的Observable,并进行非空检查。然后判断当前的并发度是否达到了最大值,如果达到了最大值,就将源Observable发射的事件放到队列中。否则,就将并发度加1,并订阅新Observable。 InnerObserver是FlatMapObserver的内部类,它实现了Observer接口,并在接收到来自新Observable的发射事件序列时,将它们合并到一个新的Observable中,并将新的Observable发射出去。 ```java static final class InnerObserver<R> implements Observer<R> { // ... @Override public void onNext(R t) { if (done) { return; } inner.onNext(t); } // ... } ``` 当所有的新Observable都完成后,FlatMapObserver会调用onComplete方法通知观察者。如果发生了异常,FlatMapObserver会调用onError方法通知观察者。同时,FlatMapObserver还实现了Disposable接口,可以通过dispose方法取消订阅。 综上所述,flatMap操作符的实现是比较复杂的,它通过创建ObservableFlatMap对象,并在subscribeActual方法中创建FlatMapObserver对象来完成转换操作。在FlatMapObserver中,它还需要实现对新Observable的订阅以及将新Observable发射的事件合并到一个新的Observable中。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值