Objective
In the example code of the previous article, you must have found the observable class. From a pure Java perspective, the observable class derives from the Classic observer pattern. The asynchronous implementation of Rxjava is based on the observer pattern and is an extended observer pattern.
Observer pattern
The Observer pattern is based on the concept of subject, subject is a special object, also called a subject or observer . When it changes, the series of objects saved by it will be notified, and this series of objects is called Observer ( Observer ). They're going to burst out of the way. A notification method, such as update, is called when the subject state is changed.
The Observer pattern works well for any of the following scenarios:
- When your architecture has two entity classes, one depends on the other, and you want them to not affect each other or to reuse them independently.
- When a changing object notifies an unknown number of objects associated with its own change.
- When a changing object notifies those objects that do not need to infer a specific type.
Typically, the class diagram for an observer pattern is this:
Observer
If you are not familiar with the observer pattern, it is highly recommended that you study it first. A detailed introduction to the observer pattern can be found in my previous article: The Observer pattern of the design pattern
Extended Observer pattern
There are 4 main roles in Rxjava:
- Observable
- Subject
- Observer
- Subscriber
Observable and subject are two "production" entities, and observer and Subscriber are two "consumption" entities. The explicit point Observable
corresponds to the observer in the Observer pattern, Observer
and to the observer Subscriber
in the Observer pattern. Subscriber
in fact, is an implementation Observer
of the abstract class, the later we analyze the source of the time will also be introduced. Subject
more complex, later analysis.
In the previous article we talked about a key concept in Rxjava: events . The observer Observer
and the Observer Observable
implement the subscribe()
subscription relationship by means of the method. This Observable
allows events to be notified when needed Observer
.
Rxjava How to use
When I am learning a new technology, I usually like to first understand how it is used, master the use of the method and then go deep digging its principle. So let's talk now about how Rxjava should be used.
First step: Create observer Observer
new Observer<Object>() { @Override public void onCompleted() { } @Override public void onError(Throwable e) { } @Override public void onNext(Object s) { } };
So simple, an observer observer created!
Big Brother You wait ..., didn't you say in the observer pattern that the observer provided only one Update method? How come there are three of these?!!
Don't worry, and listen to me slowly. In the normal observer pattern, the observer typically only provides an update () method that is used to provide a call to the observer when the State of the observer changes. The Observer Observer in Rxjava provides: onNext()
, onCompleted()
and onError()
three methods. Do you remember? At the beginning we talked about the Rxjava is based on an extended observation of this pattern implementation, where the oncompleted and onerror are an extension of the observer pattern. Ps:onnext is equivalent to the update in the normal observer pattern
Three features that are missing from the common observer pattern are added to the Rxjava:
- The Rxjava specifies that the oncompleted () method can be used as a marker when no new events are emitted;
- The framework automatically triggers the OnError () method when event handling occurs abnormally;
- At the same time observables supports chained calls, which avoids the problem of callback nesting.
Step Two: Create the Observer observable
Observable.create()
The observable method can create a crate()
observable that requires a Onsubscribe object to be created using the object, which inherits Action1. When the Observer subscribes to our observable, it passes in and executes the function as a parameter call()
.
Observable<Object> observable = Observable.create(new Observable.OnSubscribe<Object>() { @Override public void call(Subscriber<? super Object> subscriber) { }});
In addition to create (), just () and from () can also be created observable. Take a look at the following two examples:
just(T...)
Send incoming parameters in sequence
Observable observable = Observable.just("One", "Two", "Three");//上面这行代码会依次调用//onNext("One");//onNext("Two");//onNext("Three");//onCompleted();
from(T[])/from(Iterable<? extends T>)
Splits an incoming array or iterable into a Java object and sends it sequentially
String[] parameters = {"One", "Two", "Three"};Observable observable = Observable.from(parameters);//上面这行代码会依次调用//onNext("One");//onNext("Two");//onNext("Three");//onCompleted();
Step Three: The Observer observable subscribe to the Observer Observer(PS: You're right, unlike the normal observer pattern, where the observer subscribes to the observer)
With the observer and the Observer, we can subscribe to the relationship by subscribe ().
observable.subscribe(observer);
OBSERVABLE.SUBSCRIBE (Observer)
This is how you write together:
Observable.create (New Observable.onsubscribe<integer> () {@OverridePublicvoidPager(SUBSCRIBER<?Super Integer> Subscriber) {for (int i =0; I <5; i++) {subscriber.onnext (i);} subscriber.oncompleted (); }}). Subscribe (New Observer<integer> () {@Override public void oncompleted() {System.out.println ("oncompleted");} @Override public void onError(Throwable e) {System.out.println ("OnError");} @Override public void onNext(Integer Item) {SYSTEM.OUT.PRINTLN ("Item is" + Item);});
At this point a complete Rxjava call is complete.
Brother Taiwan, you jutting forced Jutting said a lot of, but I did not fix you what the hell is it?!! No hurry, I'll tell you what's going on right now.
First we used Observable.create () to create a new observable<integer>, and for the create()
method passed in a onsubscribe,onsubscribe contains a call()
method, The call subscribe()
() method is automatically triggered once we invoke the subscription. The parameter Subscriber in the call () method is actually the Observer observer in the Subscribe () method. We call()
have called 5 and 1 times in the method onNext()
onCompleted()
. After a set of process weeks, the output is as follows:
is 0Item is 1Item is 2Item is 3Item is 4onCompleted
See here may you say again, Big Brother you don't bluff me! The parameter subscriber in the Onsubscribe call () method becomes the observer in the Subscribe () method observer?!!! These two goods seem to be two different classes clearly.
Let's look at the Subscriber class first:
public abstract class Subscriber<T> implements Observer<T>, Subscription { ...}
As we can see from the source code, Subscriber is an abstract implementation class for observer, so I can be sure that the subscriber and observer types are consistent in the first place. Next we look at subscribe () This method:
PublicFinal SubscriptionSubscribe(Final observer<?Super T> observer) {If the judgment here is not related to the question we want to share, we can first ignoreIF (Observerinstanceof Subscriber) {return subscribe (SUBSCRIBER<?super t>) observer); } return subscribe (new subscriber<t> () { @Override public void oncompleted () {observer.oncompleted ();} @Override public void onerror (Throwable e) {observer.onerror (e);} @Override public void onnext (T t) {Observer.onnext (t);}});}
We see the subscribe () method inside first will pass in the observer to do a layer of proxy, convert it into subscriber. Let's look at this method inside the subscribe () method:
public final Subscription subscribe(Subscriber<? super T> subscriber) { return Observable.subscribe(subscriber, this);}
Further down the track to see what the code behind the return is doing. The subscribe (subscriber, this) method of simplifying other unrelated code is this:
private static <T> subscription subscribe ( subscriber<? super t> subscriber, observable<t> Observable) {Subscriber.onstart (); try {hook.onsubscribestart (observable, observable.onsubscribe). Call (subscriber); return Hook.onsubscribereturn (subscriber); } catch (Throwable e) {return subscriptions.unsubscribed ();}}
Let's take a look at Hook.onsubscribestart (observable, observable.onsubscribe). Call (subscriber), in front of this hook.onsubscribestart ( Observable, Observable.onsubscribe) returns the second parameter in its own parentheses observable.onsubscribe, and then calls its call method. And this observable.onsubscribe is the subscriber in the Create () method, so the whole process is straightened out. See if this is a little clearer about the Rxjava implementation process? Here also suggest that you learn new technology when more to turn over the source code, know it but also to know its why is not it.
The parameters of subscribe () can be Action1, ACTION0 in addition to observer and subscriber, and this is a simpler callback with only a call (T) method; it is too simple to introduce in detail!
Asynchronous
The beginning of the previous article says that Rxjava is to handle asynchronous tasks. But by default we are on which thread calls subscribe () on which thread produces the event, and in which thread the event is consumed. How do you do it asynchronously? Rxjava provided us with scheduler for thread scheduling, so let's take a look at what scheduler Rxjava provides.
Rxjava also provides us with subscribeOn()
observeOn()
two methods to specify observable and observer running threads.
Observable.from(getCommunitiesFromServer()) .flatMap(community -> Observable.from(community.houses)) .filter(house -> house.price>=5000000).subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(this::addHouseInformationToScreen);
You should be impressed with the code above, and that's exactly what we did in our last article. subscribeOn(Schedulers.io())
a series of events, such as getting a cell list, processing listings, and so on, is run in an IO thread, observeOn(AndroidSchedulers.mainThread())
specifying that the action on the screen to display the listing is performed on the UI thread. This is done in the sub-thread to get listings, the main thread to display the listings.
Okay, so we'll talk about this in the Rxjava series. Next we will continue to introduce more APIs and their internal principles.
Links: https://www.jianshu.com/p/ba61c047c230
Rxjava Series 2 (basic concept and introduction to use)