RxJava数据转化源码解析

本文深入解析RxJava的工作原理,从just方法创建数据开始,通过map操作实现数据转换,并详细介绍了subscribe方法触发整个流程的执行机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

RxJava

最近工作中使用了RxJava,于是阅读了一下RxJava的源码,方便理解和使用RxJava。

主要两个优势

  1. 方便的线程调度
  2. 方便高效的数据转化

转载请保留原文链接:http://blog.youkuaiyun.com/u010593680/article/details/53896316

先给一个简单的使用数据转化的例子:

    Observable.just("string")
            .map(new Func1<String, Integer>() {
                @Override
                public Integer call(String s) {
                    return s.hashCode();
                }
            })
            .subscribe(new Action1<Integer>() {
                @Override
                public void call(Integer integer) {
                    System.out.print("value : " + integer);
                }
            });

上面的例子是将String转化成Integer的例子,接下来开始分析执行流程
后面会分析各个方法的实现:

RxJava整体代码结构:生产者消费者模式

生产者就是创造数据的对象:例如just方法就是产生数据的方法,生产出来的数据才能够进行数据转化、给监听者subscriber消费
消费者:subscriber,用户调用的subscribe()设置的监听者

public static <T> Observable<T> just(final T value) {
    return ScalarSynchronousObservable.create(value);
}

在ScalarSynchronousObservable中只是调用了设置onSubscribe为JustOnSubscribe

protected ScalarSynchronousObservable(final T t) {
    super(hook.onCreate(new JustOnSubscribe<T>(t)));
    this.t = t;
}

在JustOnSubscribe中设置了监听者subscriber的生产者

static final class JustOnSubscribe<T> implements OnSubscribe<T> {
    final T value;

    JustOnSubscribe(T value) {
        this.value = value;
    }

    @Override
    public void call(Subscriber<? super T> s) {
        s.setProducer(createProducer(s, value));
    }
}

看下createProducer方法:

static <T> Producer createProducer(Subscriber<? super T> s, T v) {
    if (STRONG_MODE) {//默认为false
        return new SingleProducer<T>(s, v);
    }
    return new WeakSingleProducer<T>(s, v);
}

SingleProducer和WeakSingleProducer操作流程基本一样,只是SingleProducer是线程安全的

static final class WeakSingleProducer<T> implements Producer {
    final Subscriber<? super T> actual;
    final T value;
    boolean once;

    public WeakSingleProducer(Subscriber<? super T> actual, T value) {
        this.actual = actual;
        this.value = value;
    }

    @Override
    public void request(long n) {//数据产生后会调用该方法
        if (once) {
            return;
        }
        if (n < 0L) {
            throw new IllegalStateException("n >= required but it was " + n);
        }
        if (n == 0L) {
            return;
        }
        once = true;
        Subscriber<? super T> a = actual;
        if (a.isUnsubscribed()) {//如果已经解绑了,就不处理了
            return;
        }
        T v = value;
        try {
            a.onNext(v);
        } catch (Throwable e) {
            Exceptions.throwOrReport(e, a, v);//有异常会调用OnError
            return;
        }

        if (a.isUnsubscribed()) {
            return;
        }
        a.onCompleted();//执行完onNet,没异常就执行onCompleted
    }
}

前面为上游生产者代码,较为简单,就不细讲了,还是把重点放在比较重要的方法上

subscribe方法:使rxjava操作开始执行

subscribe前的方法调用只是作为设置,只有当subscribe方法被调用,所设置的操作才会被开始执行。来看下为什么

public final Subscription subscribe(Subscriber<? super T> subscriber) {
    return Observable.subscribe(subscriber, this);
}

static <T> Subscription subscribe(Subscriber<? super T> subscriber, Observable<T> observable) {
 // 必须有监听者
    if (subscriber == null) {
        throw new IllegalArgumentException("subscriber can not be null");
    }
    if (observable.onSubscribe == null) {//必须有操作,如just的生产者操作
        throw new IllegalStateException("onSubscribe function can not be null.");
        /*
         * the subscribe function can also be overridden but generally that's not the appropriate approach
         * so I won't mention that in the exception
         */
    }

    // 开始调用监听者的方法
    subscriber.onStart();

    /*
     * See https://github.com/ReactiveX/RxJava/issues/216 for discussion on "Guideline 6.4: Protect calls
     * to user code from within an Observer"
     */
    // if not already wrapped
    if (!(subscriber instanceof SafeSubscriber)) {//转化为SafeSubscriber
        // assign to `observer` so we return the protected version
        subscriber = new SafeSubscriber<T>(subscriber);
    }

    // The code below is exactly the same an unsafeSubscribe but not used because it would 
    // add a significant depth to already huge call stacks.
    try {
        // allow the hook to intercept and/or decorate
        hook.onSubscribeStart(observable, observable.onSubscribe).call(subscriber);//调用observable.onSubscribe的call方法
        return hook.onSubscribeReturn(subscriber);
    } catch (Throwable e) {
        // special handling for certain Throwable/Error/Exception types
        Exceptions.throwIfFatal(e);
        // in case the subscriber can't listen to exceptions anymore
        if (subscriber.isUnsubscribed()) {
            RxJavaPluginUtils.handleException(hook.onSubscribeError(e));
        } else {
            // if an unhandled error occurs executing the onSubscribe we will propagate it
            try {
                subscriber.onError(hook.onSubscribeError(e));
            } catch (Throwable e2) {
                Exceptions.throwIfFatal(e2);
                // if this happens it means the onError itself failed (perhaps an invalid function implementation)
                // so we are unable to propagate the error correctly and will just throw
                RuntimeException r = new OnErrorFailedException("Error occurred attempting to subscribe [" + e.getMessage() + "] and then again while trying to pass to onError.", e2);
                // TODO could the hook be the cause of the error in the on error handling.
                hook.onSubscribeError(r);
                // TODO why aren't we throwing the hook's return value.
                throw r;
            }
        }
        return Subscriptions.unsubscribed();
    }
}

subscribe方法代码实际上只是进行了以下操作:
* 调用subscriber.onStart();
* 将subscriber转化为SafeSubscriber
* 调用observable.onSubscribe.call(subscriber),onSubscribe就是实际的线程调度,数据转化等操作的包装对象,此时这些操作才会真正执行。
* 异常处理

SafeSubscriber的onCompleted,onError方法都会调用unsubscribe();所以只有需要提前结束时才需要调用unsubscriber()

public class SafeSubscriber extends Subscriber {

private final Subscriber<? super T> actual;

boolean done = false;

public SafeSubscriber(Subscriber<? super T> actual) {
    super(actual);
    this.actual = actual;
}

/**
 * Notifies the Subscriber that the {@code Observable} has finished sending push-based notifications.
 * <p>
 * The {@code Observable} will not call this method if it calls {@link #onError}.
 */
@Override
public void onCompleted() {
    if (!done) {
        done = true;
        try {
            actual.onCompleted();
        } catch (Throwable e) {
            // we handle here instead of another method so we don't add stacks to the frame
            // which can prevent it from being able to handle StackOverflow
            Exceptions.throwIfFatal(e);
            RxJavaPluginUtils.handleException(e);
            throw new OnCompletedFailedException(e.getMessage(), e);
        } finally {
            try {
                // Similarly to onError if failure occurs in unsubscribe then Rx contract is broken
                // and we throw an UnsubscribeFailureException.
                unsubscribe();
            } catch (Throwable e) {
                RxJavaPluginUtils.handleException(e);
                throw new UnsubscribeFailedException(e.getMessage(), e);
            }
        }
    }
}

map(operator)转化操作

map操作需要Lift帮助实现的,这里先说map的转化操作

public final <R> Observable<R> map(Func1<? super T, ? extends R> func) {
    return lift(new OperatorMap<T, R>(func));
}

关键代码在OperatorMap的call中:

@Override
public Subscriber<? super T> call(final Subscriber<? super R> o) {
    MapSubscriber<T, R> parent = new MapSubscriber<T, R>(o, transformer);
    //包装下游的subscriber生成新的MapSubscriber,
    //以后生产者生产出产品后会先调用MapSubscriber的onNext等方法
    o.add(parent);
    return parent;
}

map方法的call方法把subcriber包装成一个
MapSubscriber,而真正的数据转化在MapSubscriber中完成的。

    public MapSubscriber(Subscriber<? super R> actual, Func1<? super T, ? extends R> mapper) {
        this.actual = actual;
        this.mapper = mapper;
    }

    @Override
    public void onNext(T t) {
        R result;

        try {
            result = mapper.call(t);//先执行map中用户定义的转化操作
        } catch (Throwable ex) {
            Exceptions.throwIfFatal(ex);
            unsubscribe();
            onError(OnErrorThrowable.addValueAsLastCause(ex, t));
            return;
        }

        actual.onNext(result);//将转化后的值交给下游继续处理
    }

Lift操作

上部份代码还是比较容易理解的,只是有个问题就是: map操作在传入subcriber之前, 为什么map能包装到 下游的subcriber?
这个事情主要是lift方法中进行的转化

public final <R> Observable<R> lift(final Operator<? extends R, ? super T> operator) {
    return new Observable<R>(new OnSubscribeLift<T, R>(onSubscribe, operator));
}

每次都新建一个Observable,Observable再将OnSubscribeLift保存到onSubscribe,也就是新lift对onSubscribe进行了包装

protected Observable(OnSubscribe<T> f) {
    this.onSubscribe = f;
}

新的onSubscribe变成了OnSubscribeLift,在OnSubscribeLift类中call方法,call方法在subscribe()方法调用时,就会调用OnSubscribeLift的call方法,同时传入subscriber,那么OnSubscribeLift就获取到了下游的subscriber,之后OnSubscribeLift

@Override
public void call(Subscriber<? super R> o) {
    try {
        Subscriber<? super T> st = hook.onLift(operator).call(o);//hook默认操作就是return operator;相当于没有进行操作,所以这句代码默认为operator.call(o),这个operator可以是各种数据转化的操作,包括[下一篇的线程调度observeOn](http://blog.youkuaiyun.com/u010593680/article/details/53911475)切换线程操作
        try {
            // new Subscriber created and being subscribed with so 'onStart' it
            st.onStart();
            parent.call(st);
        } catch (Throwable e) {
            // localized capture of errors rather than it skipping all operators 
            // and ending up in the try/catch of the subscribe method which then
            // prevents onErrorResumeNext and other similar approaches to error handling
            Exceptions.throwIfFatal(e);
            st.onError(e);
        }
    } catch (Throwable e) {
        Exceptions.throwIfFatal(e);
        // if the lift function failed all we can do is pass the error to the final Subscriber
        // as we don't have the operator available to us
        o.onError(e);
    }
}

每次都会新建一个Observable,并传入OnSubscribeLift作为构造函数参数
主要实现在OnSubscribeLift,在call方法中进行:
1. 调用当前数据转化操作的call方法,获得返回参数Subscriber
2. 调用Subscriber的onStart方法
3. 执行之前的onSubscribe的call方法,并传入1中返回值
上面的操作基本上就是模拟subscribe()完成的事,让Subscriber的生命周期完整

just方法是 生产者 :新建一个Observable,Observable保存了数据,生成了onSubscribe其onSubscibe只是简单的生产了数据,调用下游的subscriber的onNext等方法

梳理例子的运行过程:

  • just新建一个Observable,Observable保存了数据,生成了onSubscribe其onSubscibe只是简单的生存了数据,调用下游的subscriber的onNext等方法
  • map操作用了Lift新建一个Observable,该Observable的OnSubscribe保存了数据转化的操作
    subscribe( subscriber )方法:调用上面操作生成的Observable.onSubscribe的call方法,并传入subscriber,即相当于上一步的lift操作
  • lift操作先调用map的call方法包装subscriber方法,生成mapSubscriber
  • 接着,lift操作调用了just生成的onSubscribe的call方法,于是数据生成,调用下游的subscriber(即mapSubscriber)的onNext方法
    map进行了数据转化,并把转化后的值传到被包装的subscriber的onNext方法
  • 结束

下一篇讲Rxjava的线程调度的实现

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值