EventBus与RxJava
总的来说,EventBus是一款针对Android优化的发布/订阅事件总线,主要功能是替代Intent,Handler,BroadCast在Fragment,Activity,Service,线程之间传递消息。而Rxjava则是一种基于异步数据流的处理方案。如果一个订阅者需要注册多个事件的时候,Rxjava需要一个个单独的注册,而EventBus则可以实现一个订阅者订阅多个事件,和一个事件对应多个订阅者。
EventBus
EventBus是一个Android端优化的publish/subscribe消息总线,简化了应用程序内各组件间、组件与后台线程间的通信。比如请求网络,等网络返回时通过Handler或Broadcast通知UI,两个Fragment之间需要通过Listener通信,这些需求都可以通过EventBus实现。EventBus仅仅适合当做组件间的通讯工具使用,主要用来传递消息,避免搞出一大堆的interface。
使用
添加依赖
使用EventBus之前需要添加相关的依赖:
compile 'org.greenrobot:eventbus:3.0.0'
然后在onStart()方法中注册它,在onStop()方法中消耗。
//注册eventBus @Override protected void onStart() { super.onStart(); EventBus.getDefault().register(this); } //取消注册 @Override protected void onStop() { super.onStop(); EventBus.getDefault().unregister(this); }
在需要接受的地方添加订阅者(使用@Subscribe注解),@Subscribe注解来描述一个public无返回值的非静态方法,注解后面可以跟threadMode,来给定订阅者处理事件所在的线程。
@Subscribe(threadMode = ThreadMode.MAIN) public void onEventMainThread(IdEvent event) { if (event != null) { } }
EventBus包含4个ThreadMode:
- ThreadMode.POSTING
事件的处理在和事件的发送在相同的进程,所以事件处理时间不应太长,不然影响事件的发送线程,而这个线程可能是UI线程; - ThreadMode.MAIN
事件的处理会在UI线程中执行,事件处理不应太长时间; - ThreadMode.BACKGROUND
事件的处理会在一个后台线程中执行,尽管是在后台线程中运行,事件处理时间不应太长; - ThreadMode.ASYNC
事件处理会在单独的线程中执行,主要用于在后台线程中执行耗时操作,每个事件会开启一个线程(有线程池),但最好限制线程的数目。
例如:
/** * 在后台线程中执行,如果当前线程是子线程,则会在当前线程执行,如果当前线程是主线程,则会创建一个新的子线程来执行 * @param event */ @Subscribe(threadMode = ThreadMode.BACKGROUND) public void onEventBackgroundThread(MessageEvent event){ System.out.println("onEventBackgroundThread::"+" "+Thread.currentThread().getName()); } /** * 创建一个异步线程来执行 * @param event */ @Subscribe(threadMode = ThreadMode.ASYNC) public void onEventAsync(MessageEvent event){ System.out.println("onEventAsync::"+" "+Thread.currentThread().getName()); } /** * 在主线程中运行 * @param event */ @Subscribe(threadMode = ThreadMode.MAIN) public void onEventMain(MessageEvent event){ System.out.println("onEventMain::"+" "+Thread.currentThread().getName()); } /** *默认的线程模式,在当前线程下运行。如果当前线程是子线程则在子线程中,当前线程是主线程,则在主线程中执行。 * @param event */ @Subscribe(threadMode = ThreadMode.POSTING) public void onEventPosting(MessageEvent event){ System.out.println("onEventPosting::"+" "+Thread.currentThread().getName()); }
发布者是在主线程还是子线程,发布的消息在所有定义好的实体类型订阅者中都可以接收到消息。也就是,可以实现一个订阅者订阅多个事件,和一个事件对应多个订阅者。
EventBus.getDefault().post(new MessageEvent("hello"));
RxJava
RxJava 在 GitHub 主页上的自我介绍是 "a library for composing asynchronous and event-based programs using observable sequences for the Java VM",翻译成中文是,一个在 Java VM 上使用可观测的序列来组成异步的、基于事件的程序的库,也就是一个异步事件库。
RxJava 的优势即是简洁,但它的简洁的与众不同之处在于,随着程序逻辑变得越来越复杂,它依然能够保持简洁。
使用
使用RxJava之前需要先添加相关的依赖:
compile 'io.reactivex.rxjava2:rxjava:2.1.8' compile 'io.reactivex.rxjava2:rxandroid:2.1.8'
使用RxJava之前,有以下几个概念需要注意:
- Observeable(被观察者)/Observer(观察者)
- Flowable(被观察者)/Subscriber(观察者)
//被观察者在主线程中,每1ms发送一个事件 Observable.interval(1, TimeUnit.MILLISECONDS) //.subscribeOn(Schedulers.newThread()) //将观察者的工作放在新线程环境中 .observeOn(Schedulers.newThread()) //观察者处理每1000ms才处理一个事件 .subscribe(new Action1() { @Override public void call(Long aLong) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } });
2.x中提供了以上两种观察者与被观察者的关系。
Observeable用于订阅Observer,是不支持背压的,而Flowable用于订阅Subscriber,是支持背压(Backpressure)的。
背压的概念是:指在异步场景中,被观察者发送事件速度远快于观察者的处理速度的情况下,一种告诉上游的被观察者降低发送速度的策略。
Flowable<String> t = Flowable.create(new FlowableOnSubscribe<String>() { @Override public void subscribe(FlowableEmitter<String> e) throws Exception { e.onNext("hello Rx2.0."); e.onComplete(); } }, BackpressureStrategy.BUFFER);
一般而言,上游的被观察者会响应下游观察者的数据请求,下游调用request(n)来告诉上游发送多少个数据。这样避免了大量数据堆积在调用链上,使内存一直处于较低水平。
我们需要调用request去请求资源,参数就是要请求的数量,一般如果不限制请求数量,可以写成Long.MAX_VALUE。如果你不调用request,Subscriber的onNext和onComplete方法将不会被调用。
Subscriber subscriber = new Subscriber() { @Override public void onSubscribe(Subscription s) { System.out.println("onSubscribe()"); s.request(Long.MAX_VALUE); } @Override public void onNext(Object o) { System.out.println(""+o.toString()); } @Override public void onError(Throwable t) { } @Override public void onComplete() { } };
除了上面这两种观察者,还有一类观察者:
- Single/SingleObserver: 返回泛型数据的结果给观察者
- Completable/CompletableObserver:返回完成的结果
- Maybe/MaybeObserver : 前两者的复合体
Rxjava内置 Scheduler
- Schedulers.immediate() :默认的,直接在当前线程运行;
- Schedulers.newThread() :启用新线程,在新线程工作;
- Schedulers.io():I/O操作(读写文件,读写数据库,网络信息交互等)、和newThread()最大的区别是:io()内部实现是一个无数量上限的线程池,可以重用空闲的线程;
- Schedulers.computation():计算所使用的 Scheduler。这个计算指的是 CPU 密集型计算,即不会被 I/O等操作限制性能的操作,例如图形的计算。这个 Scheduler 使用的固定的线程池,大小为 CPU 核数。不要把 I/O 操作放在
computation() 中,否则 I/O 操作的等待时间会浪费 CPU。 - AndroidSchedulers.mainThread(): Android专用的,指定的操作在Android的主线程运行。
subscribeOn()和observerOn()
- subscribeOn() 指定subscribe() 所发生的线程,即 Observable.OnSubcribe被激活时所处的线程,或者叫事件产生的线程。
- observerOn() 指定Subscriber 运行所在的线程,或者叫做事件消费的线程。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
iOS Audio unit(音频单元)详解 关于音频单元托管
iOS Audio unit(音频单元)详解 关于音频单元托管 iOS 提供的音频处理插件支持混合,均衡,格式转换以及录制,回放,离线呈现和实时对话(如VoIP(互联网语音协议))的实时输入/输出。您可以从 ios 应用程序动态加载并使用 - 即 主机 - 这些强大且灵活的插件(称为 音频单元)。 音频单元通常在称为音频处理图的封闭对象的上下文中工作 ,如图所示。在本例中,您的应用通过一个或多个回调函数向音频图表中的第一个音频单元发送音频,并对每个音频单元进行单独控制。I / O单元的输出 - 这个或任何音频处理图形中的最后一个音频单元 - 直接连接到输出硬件。 乍看上去 由于音频单元构成iOS音频堆栈中最低的编程层,因此要有效使用它们需要比您需要其他iOS音频技术更深的理解。除非您需要实时播放合成声音,低延迟I / O(输入和输出)或特定音频单元功能,否则请首先查看媒体播放器,AV Foundation,OpenAL或Audio Toolbox框架。这些更高级别的技术以您的名义使用音频单元,并提供重要的附加功能,如“ 多媒体编程指南”中所述。 音频单元提供快速的模块化音频处理 直接使...
- 下一篇
格安菲移动宣布更名为“别开生面移动科技” 本地化迈出关键一步
领先的加拿大Android虚拟化平台供应商格安菲移动科技Graphite Software宣布将其中文名称更改为“别开生面移动科技”, 并将使用新的品牌标识(如下图所示) ,之前的产品名称“安全空间”也将被同步取代。重塑品牌是公司在中国本土市场扩张计划的重要组成部分,更名可以更好地传达公司的价值主张,是品牌重塑的具体体现,为此,公司还聘请了前奥美高管段培力博士担任CMO领导市场变革。 “别开生面”作为中国家喻户晓的成语,意味着打开一个全新视界,它恰如其分地描述了公司产品在Android设备上的价值体现。 对于用户而言,下载一个“别开生面”空间,就像多拥有了一部手机,但只需要携带原来的硬件设备,并且每个“别开生面”空间的应用和数据互相隔离,能够对隐私进行安全保护。每一个“别开生面”空间都是一个Android虚拟化平台,单台设备上可共存多个空间, 空间之间可无缝切换。 “移动设备的虚拟空间解决方案适合多种场景,我们的目标是最大化发挥‘别开生面’解决方案的价值,超越企业市场,进入消费市场,如儿童空间和游戏空间等。同时,采用中文名称也表明我们扎根本土、服务国市场的决心,”格安菲CMO段培力这样...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS7,8上快速安装Gitea,搭建Git服务器
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- CentOS关闭SELinux安全模块
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- CentOS8编译安装MySQL8.0.19
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- CentOS8安装Docker,最新的服务器搭配容器使用
- CentOS7,CentOS8安装Elasticsearch6.8.6
- Red5直播服务器,属于Java语言的直播服务器