RxJava-RxAndroid, rxjava-rxandroid
RxJava address on github: https://github.com/ReactiveX/RxJava
RxAndroid on github: https://github.com/ReactiveX/RxAndroid
This article mainly introduces the use of RxAndroid. If you are not familiar with RxJava, You can first read the introduction Article of RxJava.
Android programs are written in Java. Android also has its own thread models, such as AsyncTask and Handler. RxJava integrates the previous items and then introduces RxAndroid. The following describes how to use it.
First, we will introduce RxAndroid in the project, mainly by introducing the following two sentences in the gradle script.
Dependencies {compile fileTree (dir: 'libs', include :['*. jar ']) testCompile 'junit: junit: 4.12 'compile 'com. android. support: appcompat-v7: 23.1.1 'compile 'com. android. support: design: 23.1.1 '// introduce RxAndroid ---- begin compile' io. reactivex: rxandroid: 1.1.0 'compile 'io. reactivex: rxjava: 1.1.0 '// introduce RxAndroid ---- end}
In this way, you can use RxAndroid In the Android code. The following example shows a code written using RxAndroid:
Observable.just("one", "two", "three", "four", "five") .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(/* an Observer */);
This code is a sample code written on the official website of RxAndroid. It can be seen that, compared with RxJava, it mainly adds the following java files:
AndroidSchedulers BuildConfig HandlerScheduler MainThreadSubscription RxAndroidPlugins RxAndroidSchedulersHook
Let's take a look at the source code of these files:
1. AndroidSchedulers class source code
public final class AndroidSchedulers { private AndroidSchedulers() { throw new AssertionError("No instances"); } private static class MainThreadSchedulerHolder { static final Scheduler MAIN_THREAD_SCHEDULER = new HandlerScheduler(new Handler(Looper.getMainLooper())); } public static Scheduler mainThread() { Scheduler scheduler = RxAndroidPlugins.getInstance().getSchedulersHook().getMainThreadScheduler(); return scheduler != null ? scheduler : MainThreadSchedulerHolder.MAIN_THREAD_SCHEDULER; }}
This class mainly provides the MainThread scheduler. In RxAndroid, The mainThread of this class is used for all foods to be processed in the main thread.
2. source code of the BuildConfig class:
public final class BuildConfig { public static final boolean DEBUG = false; public static final String APPLICATION_ID = "rx.android"; public static final String BUILD_TYPE = "release"; public static final String FLAVOR = ""; public static final int VERSION_CODE = -1; public static final String VERSION_NAME = "";}
It mainly involves some constant configurations.
3. source code of the HandlerScheduler class:
Public final class HandlerScheduler extends Scheduler {public static HandlerScheduler from (Handler handler) {// create a schedif if (Handler = null) from a handler) throw new NullPointerException ("handler = null"); return new HandlerScheduler (handler);} private final Handler handler; HandlerScheduler (Handler handler) {this. handler = handler;} @ Override public Worker createWorker () {// Override the createWorker function of Scheduler and create a Handler-based Worker return new HandlerWorker (handler );} static class HandlerWorker extends Worker {private final Handler handler; private final CompositeSubscription compositeSubscription = new CompositeSubscription (); HandlerWorker (Handler handler) {this. handler = handler;} @ Override public void unsubscribe () {compositesub.pdf. unsubscribe () ;}@ Override public boolean isUnsubscribed () {return compositesub.pdf. isUnsubscribed () ;}@ Override public subscriscrischedule (Action0 action, long delayTime, TimeUnit unit) {// Override Worker's scheduling function schedule if (compositeSubscription. isUnsubscribed () {return Subscriptions. unsubscribed ();} action = RxAndroidPlugins. getInstance (). getSchedulersHook (). onSchedule (action); final ScheduledAction scheduledAction = new ScheduledAction (action); scheduledAction. addParent (compositesubject); compositesub.pdf. add (scheduledAction); handler. postDelayed (scheduledAction, unit. toMillis (delayTime); // use Handler to process this scheduling action ScheduleAction scheduledAction. add (Subscriptions. create (new Action0 () {@ Override public void call () {handler. removeCallbacks (scheduledAction); // This statement ensures that this action can be promptly removed from Handler when the scheduling action is canceled); return scheduledAction ;} @ Override public subscribe schedule (final Action0 action) {return schedule (action, 0, TimeUnit. MILLISECONDS );}}}
The handlerschedler class is the schedler class that uses Handler as the processing core.
4. mainthreadsubtasks class source code:
Public abstract class mainthreadsubpartition implements subparts {public static void verifyMainThread () {// static method to determine whether the current thread is the main thread if (Looper. myloments ()! = Logoff. getMainLooper () {throw new IllegalStateException ("Expected to be called on the main thread but was" + Thread. currentThread (). getName () ;}} private final AtomicBoolean unsubscribed = new AtomicBoolean (); @ Override public final boolean isUnsubscribed () {return unsubscribed. get () ;}@ Override public final void unsubscribe () {// cancel subscription of the main thread if (unsubscribed. compareAndSet (false, true) {if (logoff. mylogoff () = logoff. getmainlogoff () {// if the main thread directly performs onUnsubscribe ();} else {AndroidSchedulers. mainThread (). createWorker (). schedule (new Action0 () {// if it is not the main thread, create an Action and put it in the main thread to execute @ Override public void call () {onUnsubscribe () ;}}}}} protected abstract void onUnsubscribe ();}
The mainthreadsubscribe class is mainly concerned with the execution thread of unsubscribe. Here we take all the methods to ensure that it is executed in the main thread.
5. source code of the RxAndroidPlugins class:
Public final class RxAndroidPlugins {// The main function of this class is to maintain a RxAndroidSchedulersHook private static final RxAndroidPlugins INSTANCE = new RxAndroidPlugins (); public static RxAndroidPlugins getInstance () {return INSTANCE ;} private final AtomicReference <RxAndroidSchedulersHook> schedulersHook = new AtomicReference <RxAndroidSchedulersHook> (); RxAndroidPlugins () {}@ Beta public void reset () {schedulersHoo K. set (null);} public RxAndroidSchedulersHook getSchedulersHook () {if (schedulersHook. get () = null) {schedulersHook. compareAndSet (null, RxAndroidSchedulersHook. getDefaultInstance (); // if it is null, set a RxAndroidSchedulersHook // We don't return from here but call get () again in case of thread-race so the winner will // always get returned .} return schedulersHook. get ();} public void registerSched UlersHook (RxAndroidSchedulersHook impl) {if (! SchedulersHook. compareAndSet (null, impl) {// if the original RxAndroidSchedulerHook is null, it is held directly. Otherwise, throw new IllegalStateException ("Another strategy was already registered:" + schedulersHook. get ());}}}
We can see that RxAndroidSchedulerHook must be registered before use. Once used, it cannot be registered again.
6. source code of the RxAndroidSchedulersHook class:
public class RxAndroidSchedulersHook { private static final RxAndroidSchedulersHook DEFAULT_INSTANCE = new RxAndroidSchedulersHook(); public static RxAndroidSchedulersHook getDefaultInstance() { return DEFAULT_INSTANCE; } public Scheduler getMainThreadScheduler() { return null; } public Action0 onSchedule(Action0 action) { return action; }}
This is a default RxAndroidSchedulerHook class provided by RxAndroid. programmers can also define such a class to register in RxAndroidPlugins, but they must register before using RxAndroidPlugins.
The custom RxAndroidSchedulerHook class can override the onSchedule function. Here we will perform some processing, such as logging.
The above only illustrates the differences between RxAndroid and RxJava, and does not try to explain what RxJava is. Before reading this article, readers should first understand this problem.
Now let's take a look at the previous two examples to understand:
Public class ReactiveFragment extends Fragment {// example in the UI thread @ Override public void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); Observable. just ("one", "two", "three", "four", "five "). subscribeOn (Schedulers. newThread ()). observeOn (AndroidSchedulers. mainThread ()). subscribe (/* an Observer */);}
New Thread (new Runnable () {// examples in other threads @ Override public void run () {final Handler handler = new Handler (); // Handler Observable bound to this thread. just ("one", "two", "three", "four", "five "). subscribeOn (Schedulers. newThread ()). observeOn (handlerschedeon. from (handler )). subscribe (/* an Observer */) // perform work ,...}}, "custom-thread-1 "). start ();