Hongmeng 2.0 beta version released, partners to double yi has a new learning target. (Flip the table! There’s no end to it!! Since it is to use Java programming, how can the RxJava this god!

Target: Main thread task scheduler

Speaking of RxJava, convenient thread scheduling is its very important feature, in the Android system, RxAndroid library has provided a mature main thread scheduler, the goal of this paper is to reference its ideas to achieve the main thread scheduler under the Hongmon system.

The HarmonyScheduler can be implemented based on the Handler Message communication framework provided by HarmonyScheduler, which is similar to Android.

Implementation scheme

Following the RxAndroid thread, the core logic for scheduling asynchronous tasks to the main thread is to wrap Runnable to be executed and then send it to the main thread via EventHandler for execution.

Core scheduling and end scheduling methods.

private static final class HandlerWorker extends Worker { private final RunnableObjHandler handler; private final boolean async; private volatile boolean disposed; private static AtomicLong count = new AtomicLong(); // Each time a new Worker is created, the param parameter is defined to remove all tasks created by the worker.dispose () method private final Long paramForDispose; HandlerWorker(RunnableObjHandler handler, boolean async) { this.handler = handler; this.async = async; paramForDispose = count.incrementAndGet(); } @Override // @SuppressLint("NewApi") // Async will only be true when the API is available to call. public Disposable schedule(Runnable run, long delay, TimeUnit unit) { if (run == null) throw new NullPointerException("run == null"); if (unit == null) throw new NullPointerException("unit == null"); if (disposed) { return Disposable.disposed(); } run = RxJavaPlugins.onSchedule(run); Dispose () ScheduledRunnable Scheduled = new ScheduledRunnable(handler, run); // Message Message = message.obtain (handler, scheduled); // message.obj = this; // Used as token for batch disposal of this worker's runnables. // // if (async) { // message.setAsynchronous(true); // } // // handler.sendMessageDelayed(message, unit.toMillis(delay)); // // // Re-check disposed state for removing in case we were racing a call to dispose(). // if (disposed) { // handler.removeCallbacks(scheduled); // return Disposable.disposed(); // You can see that the InnerEvent instance is wrapped by the Runnable parameter and sent to the main thread by the handler. // The InnerEvent instance cannot be obtained by the Runnable parameter. Therefore, various Dispose logic cannot be implemented according to Android. // My solution is to pass the Runnable to the InnerEvent. Object, and then customize the Handler to handle the InnerEvent by forcing the object parameter. // paramForDispose is a flag bit of type long (fixed value defined by HandlerWorker instantiation), used to mark all Runnable dispatched by the Worker, set to param parameter, // Dispose can remove single task according to object. InnerEvent message = InnerEvent. Get (handler.getinnereventid ())); message.object = scheduled; message.param = paramForDispose; handler.sendEvent(message, unit.toMillis(delay)); // Re-check disposed state for removing in case we were racing a call to dispose(). If (disposed) {// Through object Parameter to remove the InnerEvent of the currently built ScheduledRunnable. This method must specify InnerEventId, So handler.removeEvent(handler.getinnereventid (), scheduled) is provided in custom handlers; return Disposable.disposed(); } return scheduled; } @Override public void dispose() { disposed = true; // handler.removeCallbacksAndMessages(this /* token */); RemoveEvent (handler. GetInnerEventId (), paramForDispose); // Remove all InnerEvent handler. } @Override public boolean isDisposed() { return disposed; }}Copy the code

ScheduledRunnable wrapper classes

private static final class ScheduledRunnable implements Runnable, Disposable { private final RunnableObjHandler handler; private final Runnable delegate; private volatile boolean disposed; // Tracked solely for isDisposed(). ScheduledRunnable(RunnableObjHandler handler, Runnable delegate) { this.handler = handler; this.delegate = delegate; } @Override public void run() { try { delegate.run(); } catch (Throwable t) { RxJavaPlugins.onError(t); } } @Override public void dispose() { // handler.removeCallbacks(this); handler.removeEvent(handler.getInnerEventId(), this); disposed = true; } @Override public boolean isDisposed() { return disposed; }}Copy the code

The custom Handler

static class RunnableObjHandler extends EventHandler { private static AtomicInteger count = new AtomicInteger(); // Each Handler instance provides a fixed innerEventId private final int innerEventId; public RunnableObjHandler(EventRunner runner) throws IllegalArgumentException { super(runner); innerEventId = HandlerScheduler.class.hashCode() + count.incrementAndGet(); } private int getInnerEventId() { return innerEventId; } @Override protected void processEvent(InnerEvent event) { super.processEvent(event); if (event.eventId ! = innerEventId) return; Object obj = event.object; if (obj instanceof Runnable) { ((Runnable)obj).run(); }}}Copy the code

In this way, when writing hongmeng APP, you can also “flow” to move.

Complete project address, if it is helpful to you, please click a like, click a star, thank you