RxJava编程思想3-(实现简易版Rxjava,如何实现线程切换)

前言

已经使用rxjava两个月了,觉得rxjava特别好用,爱不释手。本文目的是通过几百行的代码,帮助大家理解rxjava中的链式调用,操作符,线程切换是如何实现的。如果有写的不对的地方欢迎在评论区留言,如果觉得写的可以,请点赞,关注,谢谢。

代码链接: github
目录:

RxJava编程思想1-(实现简易版Rxjava,如何基本功能和链式调用?)
RxJava编程思想2-(实现简易版Rxjava,如何实现操作符?)
RxJava编程思想3-(实现简易版Rxjava,如何实现线程切换?)

如何做线程切换?

如何实现?其实就是对被观察者的数据处理过程进行装饰,设计思想跟操作符一样,使用装饰者模式,对被被观察者的数据处理进行线程装饰。
操作起来:
先想一下,线程切换的几种场景:指定新线程,指定io线程,指定Android主线程等。
定义:抽象,约定线程的公共行为

public abstract class Scheduler {
    public abstract void scheduleDirect(Runnable runnable);
}

新线程实现:NewThreadScheduler

public class NewThreadScheduler extends Scheduler {
    private static final String TAG = "NewThreadScheduler";

    public static NewThreadScheduler getInstance(){
        return NewThreadSchedulerHolder.INSTANCE;
    }

    private static class NewThreadSchedulerHolder{
        private static NewThreadScheduler INSTANCE = new NewThreadScheduler();
    }

    @Override
    public void scheduleDirect(Runnable runnable) {
        executorService().execute(runnable);
    }

    private static ExecutorService executorService;

    private static synchronized ExecutorService executorService() {
        if (executorService == null) {
            executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(), threadFactory
                    (false));
        }
        return executorService;
    }

    private static ThreadFactory threadFactory(final boolean daemon) {
        final AtomicInteger mCount = new AtomicInteger(1);
        return new ThreadFactory() {
            @Override
            public Thread newThread(Runnable runnable) {
                Thread result = new Thread(runnable, "RxJava New Thread #" + mCount.getAndIncrement());
                result.setDaemon(daemon);
                return result;
            }
        };
    }

}

Android主线程实现AndroidSchedulers

public class AndroidSchedulers extends Scheduler {

    private static final String TAG = "AndroidSchedulers";
    private final Handler handler = new Handler(Looper.getMainLooper());

    public static AndroidSchedulers getInstance() {
        return AndroidSchedulersHolder.INSTANCE;
    }

    private static class AndroidSchedulersHolder {
        private static AndroidSchedulers INSTANCE = new AndroidSchedulers();
    }

    @Override
    public void scheduleDirect(Runnable runnable) {
        Message message = Message.obtain(handler, runnable);
        message.obj = this;
        handler.sendMessage(message);
    }

}
提供方便用户使用的静态实例对象
public final class Schedulers {
    public static final Scheduler IO = IoScheduler.getInstance();
    public static final Scheduler NEW_THREAD = NewThreadScheduler.getInstance();
    public static final Scheduler ANDROID_MAIN_THREAD = AndroidSchedulers.getInstance();

}

装饰指定线程工具做好了。下面直接使用就行了。
装饰者模式走起。。。。。。。。。。。。

实际的装饰者对象ObservableSubscribeOn :指定被观察者发射数据的线程
public class ObservableSubscribeOn<T> extends Observable<T> {

    final Scheduler scheduler;
    final ObservableSource<T> source;

    public ObservableSubscribeOn(ObservableSource<T> source, Scheduler scheduler) {
        this.source = source;
        this.scheduler = scheduler;
    }

    public final ObservableSource<T> source() {
        return source;
    }

    @Override
    public void subscribeActual(final Observer<? super T> s) {
        final SubscribeOnObserver<T> parent = new SubscribeOnObserver<T>(s);
        scheduler.scheduleDirect(new Runnable() {
            @Override
            public void run() {
                RLog.printInfo("我在这里切换");
                source.subscribe(parent);
            }
        });
    }


    static final class SubscribeOnObserver<T> implements Observer<T> {
        final Observer<? super T> actual;

        SubscribeOnObserver(Observer<? super T> actual) {
            this.actual = actual;
        }

        @Override
        public void onSubscribe() {
            actual.onSubscribe();
        }

        @Override
        public void onNext(T t) {
            CheckUtils.checkNotNull(t, "onNext called parameter can not be null");
            actual.onNext(t);
        }

        @Override
        public void onError(Throwable error) {
            actual.onError(error);

        }

        @Override
        public void onComplete() {
            actual.onComplete();
        }

    }
}
实际的装饰者对象ObservableObserveOn :指定观察者接收数据的线程
public class ObservableObserveOn<T> extends Observable<T> {

    final Scheduler scheduler;
    final ObservableSource<T> source;

    public ObservableObserveOn(ObservableSource<T> source, Scheduler scheduler) {
        this.source = source;
        this.scheduler = scheduler;
    }

    public final ObservableSource<T> source() {
        return source;
    }

    @Override
    public void subscribeActual(final Observer<? super T> s) {
        final ObserveOnObserver<T> parent = new ObserveOnObserver<T>(s, scheduler);
        source.subscribe(parent);

    }

    static final class ObserveOnObserver<T> implements Observer<T> {
        final Observer<? super T> actual;
        final Scheduler scheduler;

        public ObserveOnObserver(Observer<? super T> actual, Scheduler scheduler) {
            this.actual = actual;
            this.scheduler = scheduler;
        }

        @Override
        public void onSubscribe() {
            scheduler.scheduleDirect(new Runnable() {
                @Override
                public void run() {
                    actual.onSubscribe();
                }
            });
        }

        @Override
        public void onNext(final T t) {
            scheduler.scheduleDirect(new Runnable() {
                @Override
                public void run() {
                    CheckUtils.checkNotNull(t, "onNext called parameter can not be null");
                    actual.onNext(t);
                }
            });
        }

        @Override
        public void onError(final Throwable error) {
            scheduler.scheduleDirect(new Runnable() {
                @Override
                public void run() {
                    actual.onError(error);
                }
            });
        }

        @Override
        public void onComplete() {
            scheduler.scheduleDirect(new Runnable() {
                @Override
                public void run() {
                    actual.onComplete();
                }
            });
        }
    }

}

同样为了方便用户使用 使用和链式调用,在装饰者组件Observable中 加入工具方法

public final Observable<T> subscribeOn(Scheduler scheduler) {
        return new ObservableSubscribeOn<T>(this, scheduler);
    }

    public final Observable<T> observeOn(Scheduler scheduler) {
        return new ObservableObserveOn<T>(this, scheduler);
    }

现在就可以使用了:

Observable.create(new ObservableOnSubscribe<Integer>() {
			@Override
			public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
				RLog.printInfo("emitter发送第一个onNext,value = 1");
				emitter.onNext(1);
				RLog.printInfo("emitter发送onComplete");
				emitter.onComplete();
			}
		}).subscribeOn(Schedulers.NEW_THREAD).subscribeOn(Schedulers.IO).subscribeOn(Schedulers.NEW_THREAD).subscribeOn(Schedulers.IO).observeOn
				(Schedulers.IO).map(new Function<Integer, String>() {
			@Override
			public String apply(Integer integer) throws Exception {
				RLog.printInfo("切换线程");
				return "切换线程" + integer;
			}
		}).observeOn(Schedulers.ANDROID_MAIN_THREAD).subscribe(new Observer<String>() {

			@Override
			public void onSubscribe() {
				RLog.printInfo("Observer被订阅");
			}

			@Override
			public void onNext(String value) {
				RLog.printInfo("Observer接收到onNext,被转换之后的value = " + value);
			}

			@Override
			public void onError(Throwable e) {
				RLog.printInfo("Observer接收到onError,errorMsg = " + e.getMessage());
			}

			@Override
			public void onComplete() {
				RLog.printInfo("Observer接收到onComplete");
			}
		});

这里只是非常简单的带领大家理解rxjava主体的设计思想。为了方便理解,代码也尽可能简化到了极点。真正的rxjava源码做了很多优化,比如,数据流缓冲(背压)等。到此,大家应该对Rxjava的设计思想有了很好的理解了。其它操作符的架构设计思想是一样的,只是实现细节不同,相信看到这里在去看看rxjava源码应该很轻松就可以理解了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Android 中,使用 RxJava 可以非常方便地实现线切换RxJava 提供了几个操作符用于实现线切换,包括 `subscribeOn()` 和 `observeOn()`。 `subscribeOn()` 操作符用于指定被观察者的执行线程,而 `observeOn()` 操作符用于指定观察者的执行线程。这两个操作符可以组合使用,实现从一个线切换到另一个线程的功能。 下面是一个简单的 RxJava 实现线程的例子: ```java Observable.create(new ObservableOnSubscribe<Integer>() { @Override public void subscribe(ObservableEmitter<Integer> emitter) throws Exception { // 在子线程中执行耗时操作 Log.d("RxJava", "subscribe: " + Thread.currentThread().getName()); emitter.onNext(1); emitter.onComplete(); } }) .subscribeOn(Schedulers.newThread()) // 指定被观察者的执行线程 .observeOn(AndroidSchedulers.mainThread()) // 指定观察者的执行线程 .subscribe(new Observer<Integer>() { @Override public void onSubscribe(Disposable d) { // 订阅事件 } @Override public void onNext(Integer integer) { // 处理事件 Log.d("RxJava", "onNext: " + Thread.currentThread().getName()); } @Override public void onError(Throwable e) { // 处理错误 } @Override public void onComplete() { // 完成事件 } }); ``` 在上面的代码中,使用 `subscribeOn()` 操作符指定被观察者在新线程中执行,使用 `observeOn()` 操作符指定观察者在主线程中执行。在实际开发中,可以根据实际需求选择不同的线程。 需要注意的是,RxJava 中的线切换并不会创建新的线程,而是复用已有的线程。因此,如果需要在多个地方使用 RxJava 进行线切换,建议使用线程池来管理线程,避免创建过多的线程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值