文章主要简单结合源码分析rxjava的思想和处理方式,很多功能用法不错列举~
rxJava基本用法 :
int drawableRes = ...;
ImageView imageView = ...;
Observable.create(new OnSubscribe() {
@Override
public void call(Subscriber super Drawable> subscriber) {
Drawable drawable = getTheme().getDrawable(drawableRes));
subscriber.onNext(drawable);
subscriber.onCompleted();
}
}).subscribe(new Observer() {
@Override
public void onNext(Drawable drawable) {
imageView.setImageDrawable(drawable);
}
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
Toast.makeText(activity, "Error!", Toast.LENGTH_SHORT).show();
}
});
(rxJava 也提供了action funcrion的简单用法 原理类似,大家都知道 只有调用了Observable.subscribe() 方法 那create的逻辑才会执行.那我们就看看subscribe() 做了什么 )
源码摘取
A
public final static
return new Observable
}
B
public class Observable {
final OnSubscribe onSubscribe;
/**
* Creates an Observable with a Function to execute when it is subscribed to.
*
* Note: Use {@link #create(OnSubscribe)} to create an Observable, instead of this constructor,
* unless you specifically have a need for inheritance.
*
* @param f
* {@link OnSubscribe} to be executed when {@link #subscribe(Subscriber)} is called
*/
protected Observable(OnSubscribe f) {
this.onSubscribe = f;
}
C
public final Subscription subscribe(Subscriber super T> subscriber) {
// validate and proceed
if (subscriber == null) {
throw new IllegalArgumentException("observer can not be null");
}
if (onSubscribe == null) {
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
*/
}
// new Subscriber so onStart it
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)) {
// assign to `observer` so we return the protected version
subscriber = new SafeSubscriber(subscriber);
}
// The code below is exactly the same an unsafeSubscribe but not used because it would add a sigificent depth to alreay huge call stacks.
try {
// allow the hook to intercept and/or decorate
hook.onSubscribeStart(this, onSubscribe).call(subscriber);
return hook.onSubscribeReturn(subscriber);
} catch (Throwable e) {
// special handling for certain Throwable/Error/Exception types
Exceptions.throwIfFatal(e);
// if an unhandled error occurs executing the onSubscribe we will propagate it
try {
subscriber.onError(hook.onSubscribeError(e));
} catch (OnErrorNotImplementedException e2) {
// special handling when onError is not implemented ... we just rethrow
throw e2;
} catch (Throwable 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 RuntimeException("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();
}
}
分析:(hook这个类设计没有看明白 基本都是传递什么进取就返回什么 )
Observable 内部持有了一个Onsubscribe 的引用并且是final 的..
Observable.create(Onsubscribe )后给引用赋值,然后subscribe 时候回调它的call 方法.并且把自己引用传递过去
再回过头看例子,rxjava的机制就没那么神秘了,发布订阅模型, create 创建了一个发布者.subscribe 创建一个或者多个订阅者. create call逻辑执行完后直接把结果传递给下一个订阅者. 然后后续还有很多复杂的处理.
但rxjava想要表现的也就是通过这种方式,来解决随着编码的增多代码逻辑仍然保持最初的简洁性.
再看另一个亮点Scheduler 线程的切换
源码摘要
public final Observable subscribeOn(Scheduler scheduler) {
return nest().lift(new OperatorSubscribeOn(scheduler));
}
public final Observable> nest() {
return just(this);
}
public final static
Observable just(final T value) { return ScalarSynchronousObservable.create(value); } public final class ScalarSynchronousObservable
extends Observable { public static final ScalarSynchronousObservable create(T t) { return new ScalarSynchronousObservable (t); } private final T t; protected ScalarSynchronousObservable(final T t) { super(new OnSubscribe () { @Override public void call(Subscriber super T> s) { s.onNext(t); s.onCompleted(); } }); this.t = t; } public T get() { return t; } } -----------------------------------------------------------------------------------------------------------------
public final
Observable lift(final Operator extends R, ? super T> lift) { return new Observable (new OnSubscribe () { @Override public void call(Subscriber super R> o) { try { Subscriber super T> st = hook.onLift(lift).call(o); try { // new Subscriber created and being subscribed with so 'onStart' it st.onStart(); onSubscribe.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 if (e instanceof OnErrorNotImplementedException) { throw (OnErrorNotImplementedException) e; } st.onError(e); } } catch (Throwable e) { if (e instanceof OnErrorNotImplementedException) { throw (OnErrorNotImplementedException) 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); } } }); }
-------------------------------------------------------------------------------------------------------------------
public class OperatorSubscribeOn
implements Operator > { private final Scheduler scheduler; public OperatorSubscribeOn(Scheduler scheduler) { this.scheduler = scheduler; } @Override public Subscriber super Observable > call(final Subscriber super T> subscriber) { final Worker inner = scheduler.createWorker(); subscriber.add(inner); return new Subscriber >(subscriber) { @Override public void onCompleted() { // ignore because this is a nested Observable and we expect only 1 Observable emitted to onNext } @Override public void onError(Throwable e) { subscriber.onError(e); } @Override public void onNext(final Observable o) { inner.schedule(new Action0() { @Override public void call() { final Thread t = Thread.currentThread(); o.unsafeSubscribe(new Subscriber (subscriber) { @Override public void onCompleted() { subscriber.onCompleted(); } @Override public void onError(Throwable e) { subscriber.onError(e); } @Override public void onNext(T t) { subscriber.onNext(t); } @Override public void setProducer(final Producer producer) { subscriber.setProducer(new Producer() { @Override public void request(final long n) { if (Thread.currentThread() == t) { // don't schedule if we're already on the thread (primarily for first setProducer call) // see unit test 'testSetProducerSynchronousRequest' for more context on this producer.request(n); } else { inner.schedule(new Action0() { @Override public void call() { producer.request(n); } }); } } }); } }); } }); } }; } }
然后支持的Schedulers 类型 有Schedulers.io | Schedulers.newThread | Schedulers.computation | (默认Schedulers.immediate | Schedulers.trampoline)
主要介绍前三个
io 对应 CachedThreadScheduler 可复用线程池
newThread对应NewThreadScheduler 单个线程
computation对应EventLoopsScheduler 根据cpu计算得到的线程池
nest方法创建了一个新的发布者,lift 变换 接受之前的发布者处理完后的事件,然后包装交给后面订阅者.就在这个过程中使用Schedulers在指定的线程调度器重执行后回调给
发布者中最后交由订阅者处理