1. What is RxJava •
Rx is Reactive Extensions shorthand, translated into the expansion of the response. I.e. by sending information from the one side, and the other information in response to the core frame processing code.
• The framework led by Microsoft architect Erik Meijer team development, and open in November 2012.
• Rx library supports .NET, JavaScript and C ++ now supports almost all of the popular programming language.
• Rx most responsible ReactiveX language library maintenance organization, the more popular there RxJava / RxJS / Rx.NET, community site is reactivex.io.
• RxJava as a popular framework, relying on its source code in GitHub, in addition to supporting RxJava, except for Android also supports a framework RxAndroid
2.RxJava simplify the code in general we Andrews project, if you want to get data from the background and refreshed interface, the code is something like, let's look at an example:
new Thread() { @Override public void run() { super.run(); for (File folder : folders) { File[] files = folder.listFiles(); for (File file : files) { if (file.getName().endsWith(".png")) { final Bitmap bitmap = getBitmapFromFile(file); getActivity().runOnUiThread(new Runnable() { @Override public void run() { imageCollectorView.addImage(bitmap); } }); } } } } }.start(); 上面的代码经过多层嵌套后 可读性太差了!如果你用了RxJava 可以这样写: Observable.from(folders) .flatMap(new Func1<File, Observable>() { @Override public Observable call(File file) { return Observable.from(file.listFiles()); } }) .filter(new Func1<File, Boolean>() { @Override public Boolean call(File file) { return file.getName().endsWith(".png"); } }) .map(new Func1<File, Bitmap>() { @Override public Bitmap call(File file) { return getBitmapFromFile(file); } }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1() { @Override public void call(Bitmap bitmap) { imageCollectorView.addImage(bitmap); } });
The benefits of this writing is to reduce the levels of nesting improve the readability of the code, in addition to simplify the code, RxJava also provide specific methods for each running thread.
3. The introduction of the framework of the current RxJava has been upgraded to version 2.0, but in order to better understand RxJava, we can begin to learn from version 1.0. Andrews also order for our project to better use RxJava, may be introduced gradle script relies in the project: compile 'io.reactivex: rxandroid: 1.2.1 ' compile 'io.reactivex: rxjava: 1.1.6' Now our the project has been supported RxJava the function. 4. responsive responsive so-called core, there is nothing more than two parts, one part is responsible for sending the event / message, responds to another part of the event / message. Previously, if we want to see the news, generally you need to read the newspaper. For example, are you interested in some newspapers and magazines, then you first need to do three things:
-
Provide your home address
-
Find the corresponding newspaper
-
Subscribe to newspaper newspapers throughout the month after the above process, after a day as long as there is new information out of newspapers, magazines newspaper will be sent to your home.
The abstract code example above, the following steps:
-
Providing the viewer (because you are concerned about the content of the magazine is to observe people so you people of the event)
-
Providing the viewer (as long as there is a new magazine out of the need to inform the people concerned so the newspaper is an object to be observed)
-
Subscribe (that is, to the observer & is interrelated to the observed object will immediately notice a change between the observer observes the object of the event)
The above example demonstrates the code below: // Create an observed person. Observable Observable = Observable.create (new new Observable.OnSubscribe () {public void @Override Call (for Subscriber Subscriber) {<Super String?> //. 4 starts transmission. events // there are three types of events are onNext () onCompleted () onError ( ) // onCompleted () onError () are generally used to send an event notification observer finished, both only choose one. subscriber.onNext ( "Hello Android!"); subscriber.onNext ( "Hello Java!"); subscriber.onNext ( "Hello C!"); subscriber.onCompleted ();}});
// Create a 2 observer Subscriber subscriber = new Subscriber () { @Override public void onCompleted () {Log.i (TAG, "onCompleted");}
@Override public void onError(Throwable e) { Log.i(TAG, "onError: "+e.getLocalizedMessage()); } @Override public void onNext(String s) { Log.i(TAG, "onNext: "+s); } 复制代码
};
// 3 subscription. Observable.subscribe (up for Subscriber); output as follows: com.m520it.rxjava I / IT520: onNext: Hello Android com.m520it.rxjava I / IT520: onNext: Hello Java com.m520it.rxjava I /!! IT520: onNext: Hello C com.m520it.rxjava I / IT520:! • principle onCompleted code running the code above, when the observer subscriber is subscribed observers observable, the system will automatically call the callback inside of observable objects () . • In the call observable () method entity, such as after sending the onNext / onCompleted / onError events. • Then subscriber will be able to call back to the corresponding method. The three methods need be transmitted onNext, onError, onCompleted ordinary observer Observable variants, and variants as Single Observable, just two methods: • onSuccess - Single single value of the transmission to this method • onError - if not emitted after the desired value, Single launch a Throwable object to this method Single will only call one of these two methods, but only one call, a call to any method, terminate the subscription relationship. final Single single = Single.create (new Single.OnSubscribe () {@Override public void call (SingleSubscriber <? super String> singleSubscriber) {// first call onNext () the last call onCompleted ()//singleSubscriber.onSuccess("Hello Android !"); //只调用onError(); singleSubscriber.onError(new NullPointerException("mock Exception !")); } });
Observer observer = new Observer() { @Override public void onCompleted() { Log.i(TAG, "onCompleted "); }
@Override public void onError(Throwable e) { Log.i(TAG, "onError: "+e.getLocalizedMessage()); } @Override public void onNext(String s) { Log.i(TAG, "onNext: "+s); } 复制代码
}; Single.subscribe (observer); 6. observer variants Observer observer objects, we replaced with the above Subscriber object. Because the object itself is inherited Observer. The object implements onNext () & onCompleted () & onError () event, if we are more concerned about which event, only need to implement the corresponding method to, the following code: // Create observer Subscriber subscriber = new Subscriber () {@Override public void onCompleted () {Log.i (TAG, "onCompleted");}
@Override public void onError(Throwable e) { Log.i(TAG, "onError: "+e.getLocalizedMessage()); } @Override public void onNext(String s) { Log.i(TAG, "onNext: "+s); } 复制代码
};
// Subscribe observable.subscribe (subscriber);. The above code, if you are only interested onNext () event, but had to realize onCompleted () & onError () event such code becomes very cumbersome. Given this demand, RxJava subscription has done in the framework of specific adjustments, as follows: // Create a separate interface Action1 onNextAction = new Action1 () {@Override public void call (String s) {Log onNext for the specified event. i (TAG, "call:" + s);}};
// Subscribe observable.subscribe (onNextAction);
复制代码
I do not know if you noticed, subscribe () subscription is no longer an observer, but a specific onNext interface objects. Similar functions are as follows, we can achieve the corresponding subscription required:
public Subscription subscribe(final Observer observer) public Subscription subscribe(final Action1 onNext) public Subscription subscribe(final Action1 onNext, Action1 onError) public Subscription subscribe(final Action1 onNext, Action1 onError, Action0 onCompleted)
There is also a forEach function has a similar function:
public void forEach(final Action1 onNext) public void forEach(final Action1 onNext, Action1 onError) public void forEach(final Action1 onNext, Action1 onError, Action0 onComplete)
Var ## 7.Subject
Section 2 above is introduced in both variants of the observer, and the observer describes variants described here again subject an hermaphroditic (to be used both as an observer, may be used as an observer).
There are four types of Subject for different scenarios. They were not all present in all implementations.
###AsyncSubject
A AsyncSubject Observable only after the original is completed, the last value from the original emission of Observable. This last value it will transmit to any subsequent observer.
Posted the following codes: // Create the observed final AsyncSubject subject = AsyncSubject.create (); // Create a viewer Subscriber subscriber = new Subscriber () {@Override public void onCompleted () {Log.i (TAG, "onCompleted ");}
@Override
public void onError(Throwable e) {
Log.i(TAG, "onError");
}
@Override
public void onNext(String s) {
Log.i(TAG, "s:" + s);
}
复制代码
}; // subscribe to events subject.subscribe (subscriber); // if the event was sent observers call onCompleted (), onNext () will print the last event; if not, onNext () in any event is not printed. subject.onNext ( "Hello Android"); subject.onNext ( "Hello Java"); subject.onCompleted (); output: s: Hello Java onCompleted However, if the original Observable terminated because an error occurred, AsyncSubject will not transmit any data, but simply pass this error notification forward.
The above is the same as the observer observer codes, now emits a series of signals, and an abnormal code is as follows at the end:
subject.onNext ( "Hello Android"); subject.onNext ( "Hello Java"); // send an exception because it onNext () can not be printed subject.onError (null); ### BehaviorSubject
When the observer subscribe BehaviorSubject, an event he would subscribe to the last transmission before and after the event sent to all subscribers are printed out, if not send event before the subscription, it will default to receive constructor create (T) inside the object and subscriptions after all events, as follows: BehaviorSubject subject = BehaviorSubject.create ( "NROMAL");
Subscriber subscriber = new Subscriber() { @Override public void onCompleted() { Log.i(TAG, "onCompleted"); }
@Override
public void onError(Throwable e) {
Log.i(TAG, "onError");
}
@Override
public void onNext(Object o) {
Log.i(TAG, "onNext: " + o);
}
复制代码
}; //Subject.onNext ( "the Hello Android!"); //Subject.onNext ( "the Hello the Java!"); //Subject.onNext ( "C the Hello!"); // here to subscribe if above 3 annotations not removed, the Hello C events and subscribe to events back into effect if the above three comments // remove the print after the entry into force of the constructor NORMAL events and subscribe to the back of the entry into force of events subject.subscribe (subscriber);
subject.onNext("Hello CPP !"); subject.onNext("Hello IOS !"); PublishSubject
PublishSubject will only occur after a point of time subscription data from the original Observable emission to the observer.
Note that, PublishSubject might be a created immediately starts transmitting data, so there is a risk: Subject is created after this period of time before to have observer subscribe to it, one or more data may be lost.
Code is as follows: PublishSubject subject = PublishSubject.create ();
Action1 onNextAction1 = new Action1(){
@Override
public void call(String s) {
Log.i(TAG, "onNextAction1 call: "+s);
}
复制代码
};
Action1 onNextAction2 = new Action1(){
@Override
public void call(String s) {
Log.i(TAG, "onNextAction2 call: "+s);
}
复制代码
};
subject.onNext("Hello Android !"); subject.subscribe(onNextAction1); subject.onNext("Hello Java !"); subject.subscribe(onNextAction2); subject.onNext("Hello IOS !");
Output is as follows:
onNextAction1 call: Hello Java ! onNextAction1 call: Hello IOS ! onNextAction2 call: Hello IOS ! ReplaySubject
ReplaySubject will transmit all data from the original Observable to the observer, regardless of when they subscribe.
code show as below:
ReplaySubject subject= ReplaySubject.create();
Action1 onNextAction1 = new Action1(){
@Override
public void call(String s) {
Log.i(TAG, "onNextAction1 call: "+s);
}
复制代码
};
Action1 onNextAction2 = new Action1(){
@Override
public void call(String s) {
Log.i(TAG, "onNextAction2 call: "+s);
}
复制代码
};
subject.onNext("Hello Android !"); subject.subscribe(onNextAction1); subject.onNext("Hello Java !"); subject.subscribe(onNextAction2); subject.onNext("Hello IOS !");
Output is as follows:
onNextAction1 call: Hello Android ! onNextAction1 call: Hello Java ! onNextAction2 call: Hello Android ! onNextAction2 call: Hello Java ! onNextAction1 call: Hello IOS ! onNextAction2 call: Hello IOS ! ###Subject总结
AsyncSubject Whenever subscription only receives the last onNext () event, if the last exception occurs, it will not print any onNext () BehaviorSubject will last oNext from the front subscribe () to start printing until the end. If no call onNext before subscription (), then call the default creat (T) passed in object. If an exception after the call, onNext not printed (in any event only after PublishSubject print subscription). ReplaySubject regardless of subscription in the event will be called when sent.
Above code demonstrates how RxJava with some basic functions are implemented, we hope we can bring a different inspiration. But this is only a small share, from really far worse Rx framework used in the project. This also allows us to understand, a robust framework need to consider many things, such as scalability and readability of the code performance optimization, testability, compatibility, extreme circumstances. But sometimes in order to achieve in-depth understanding of a complex framework of principles, we need to strip these details Code, calling more attention to the logical backbone, simplify.