create()+subscribe():
This is the code Rx often writes.
Observable<String> observable = Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
subscriber.onNext("content");
subscriber.onCompleted();
}
});
Subscriber<String> subscriber = new Subscriber<String>() {
@Override
public void onCompleted() {
Log.e("onCompleted", "onCompleted");
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(String s) {
Log.e("onNext", s);
}
};
observable.subscribe(subscriber);
1. This code returns an Observable object and hook.onCreate(f) is passed as a parameter.
public static <T> Observable<T> create(OnSubscribe<T> f) {
return new Observable<T>(hook.onCreate(f));
}
2. Looking at the code, we can see that the input parameter f is actually returned.
public <T> OnSubscribe<T> onCreate(OnSubscribe<T> f) {
return f;
}
3. Calling create actually assigns the implementation class of OnSubscribe to the member of Observable: onSubscribe
protected Observable(OnSubscribe<T> f) {
this.onSubscribe = f;
}
public class Observable<T> {
final OnSubscribe<T> onSubscribe;
...
}
Then get this onSubscribe from outside.
4. When observable calls subscribe, look at onSubscribeStart (xx,xx,xx), and you will find that the return is the second parameter, observable.onSubscribe, mentioned in 3.
static <T> Subscription subscribe(Subscriber<? super T> subscriber, Observable<T> observable) {
...
try {
hook.onSubscribeStart(observable, observable.onSubscribe).call(subscriber);
return hook.onSubscribeReturn(subscriber);
} catch (Throwable e) {
...
return Subscriptions.unsubscribed();
}
}
//Calling onSubsribe.call(subscriber) calls back the call method we implemented when we got observable, and calls the corresponding onNext in the call.
map():
return Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
subscriber.onNext(text);
}
}).map(new Func1<String, List<String>>() {
@Override
public List<String> call(String s) {
List<String> list = new ArrayList<>();
list.add(s + 1);
list.add(s + 2);
return list;
}
});
1. As you can see, you can get a new Observable object through map and "new OnSubscribeLift"
2. Call subscribe after map, which can be written as: new OnSubscribeLift
3. Looking at OnSubscribeLift, you will inevitably call back the secondary call method. You can see that hook.onLift(operator) returns the operator.
public <T, R> Operator<? extends R, ? super T> onLift(final Operator<? extends R, ? super T> lift) {
return lift;
}
4. When the map was first called, a new Operator Map was created, where the operator is an example. This call method will inevitably be called, where o is the implementation class parameter that we pass in subscribe, and transformer is the implementation class parameter of the implementation call method that map passes in. Returns the MapSubscriber instance.
public final class OperatorMap<T, R> implements Operator<R, T> {
final Func1<? super T, ? extends R> transformer;
public OperatorMap(Func1<? super T, ? extends R> transformer) {
this.transformer = transformer;
}
@Override
public Subscriber<? super T> call(final Subscriber<? super R> o) {
MapSubscriber<T, R> parent = new MapSubscriber<T, R>(o, transformer);
o.add(parent);
return parent;
}
}
5. In 2, the code goes to parent.call(st); the MapSubscriber instance returned in 4 is passed in. (Specifically, this parent is the implementation class passed in after invoking create in 1, which assigns the value of onSubscribe for the first time, that is, onSubscribe of the previous level). So: Callback at this point, the implementation class that the Create method passed in to implement the call method, goes to subscriber.onNext(); callback the following code
static final class MapSubscriber<T, R> extends Subscriber<T> {
...
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);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
unsubscribe();
onError(OnErrorThrowable.addValueAsLastCause(ex, t));
return;
}
actual.onNext(result);
}
@Override
public void onError(Throwable e) {
...
actual.onError(e);
}
@Override
public void onCompleted() {
...
actual.onCompleted();
}
...
}
6. Walk to result = mapper.call(t); call back the implementation class of the call method in the map parameter, convert it, get a new type, call actual.onNext(result) again; call back onNext () in the implementation class we passed in in the subscribe method, and send back the transformed type.
The whole process is completely in line with the observer mode, similar to the process of setting up a monitor and waiting for the corresponding time to call back.