2.2和cs2.0有什么不同同

&的最新主题
提示: 作者被禁止或删除 内容自动屏蔽
个人觉得2.4- -
愚见。。。。
提示: 作者被禁止或删除 内容自动屏蔽
专业回答:详情请咨询度娘
F2.0 光圈大& & 光线不足的时候,单位时间进光量大,容易在夜晚拍出好照片
2.4的锐度细节保留的比较好,但是暗光情况下一般般。光圈越小进光度就少,从而导致夜景一般般。像2.0大光圈夜景暗光情况下质量就比较明显。你仔细观察一下, F2.0的摄像头的孔径要比F2.4的稍微大一些,所以F2.0的摄像头的成像能力略强一些, 因为光线的透过量比较多的缘故。2.0的虚化好于2.4,但并不代表画质肯定好于2.4,这取决于镜头的素质,也就是价格。 理论上光圈越大越好,与焦距无关。光圈越大可以得到更高的快门速度。当然在拍照过程中重要的是要选择合适的光圈,而不是一味的追求最大光圈。
& && && &光圈指的是镜头的通光孔径。
一般来说,f数值越小表示光圈越大,数值越大表示光圈越小。
光圈大可以在一定程度上提高快门速度,在光线条件较暗的时候,手持拍摄清晰的几率会更大;并且大光圈景深浅,在拍摄中经常使用大光圈来虚化背景或前景,起到突出主体、简化画面的作用。
小光圈景深大,在拍摄风景的时候经常使用小光圈来使照片中的更多景物都处于清晰的范围内。
.对于镜头来说,一般定焦镜头的光圈都会比变焦镜头大;在变焦镜头中恒定大光圈的镜头比较好,当然相应的价格也比较高。
.这些基本知识三言两语也只能说个大概,建议你还是找一些相关书籍看看,要详细讲解的,估计可以简单写个小册子了,呵呵。
说简单点,大光圈2.0拍近景 微距方面比较好细节到位,但是远景建筑物方面细节素质不行,
而小光圈2.4拍远景建筑物方面细节素质可以,但是拍近景 暗光情况下一般般。
[ 本帖最后由 花城ゞ 于
23:30 编辑 ]
光圈越大,越好,1、曝光越足,2、层次感越深;大光圈的数值越小哦,F2.0的光圈大于F2.4
快门越大则有利有弊,1、好在越能抓高速运动的细节,也可以理解为防抖越强;2、弊端在快门大则取景时间短而曝光不足
最后说明曝光当然是越足越好,还原细节清晰画质等。
就楼上说的光圈影响锐度我不同意,锐度是涉及到相机处理器的计算公式的,或者说涉及到机身机械性能影响到的对焦准确性,锐度的侧重也会影响细节的把握。这是一个侧重于锐度或细节的倾向性问题
如果把成像的质量看成锐度的话,毫无疑问光圈越大曝光越足细节越真实,而锐度越大。
[ 本帖最后由 bb8281 于
23:48 编辑 ]
理论上,光圈越大越好,也就是说F2.0>F2.2>F2.4,大光圈意味着进光量要大于小光圈,但是个人觉得对于手机,受限于传感器与镜头尺寸,不必太过于纠结于光圈大小。起码我觉得MX2以F2.4的光圈,拍出的微距一点都不弱于标称光圈F1.8的。
光圈是指单位时间里的进光量,在光线较暗时,光圈越大(数值越小),快门时间就短,因而更易捕获清晰的图像。
光圈也是决定景深大小的关键参数,光圈越大,景深越小,对于拍风景之类需要展现各方位细节的图像,就需要更小的光圈。
假如你喜欢拍人像、微距的话,就需要一部大光圈(F2.0)的手机。
真心希望不久将来,手机摄像头也能有调节光圈这个功能。
提示: 作者被禁止或删除 内容自动屏蔽
内容这要看你用手机拍什么样东西,拍摄距离是多少,想不想让景深覆盖想要拍摄东西的全部,例如:
以上大光圈(f2.0)拍人像,摄距近,有可能鼻子清晰,耳朵模糊(景深浅),但同样的摄距小光圈(f2.4)就有可能拍出的鼻子耳朵都清晰。
每个人的喜欢不同,有的喜欢人像清晰,背景建筑模糊。有的人喜欢人和背景建筑都清晰。
这要看你用手机拍什么样东西,拍摄距离是多少,想不想让景深覆盖想要拍摄东西的全部,例如:
以上大光圈(f2.0)拍人像,摄距近,有可能鼻子清晰,耳朵模糊(景深浅),但同样的摄距小光圈(f2.4)就有可能拍出的鼻子耳朵都清晰。
每个人的喜欢不同,有的喜欢人像清晰,背景建筑模糊。有的人喜欢人和背景建筑都清晰。
各有利弊,光圈越大单位时间进光量越大,相对曝光时间短,但是大光圈景深小,只适合拍微距等比较近的景物。而想要拍相对较远的风景的话需要小光圈来把各个层次的景物都拍清楚。所以没有最好的,各有各的用处,要不单反上也不用出各种镜头了。
这个不就是光圈范围大小么。
米二2.0的。。
主要看你拍什么
光圈越大(就是f值越小)
镜头进光量就越大(光线暗的情况下也可拍的清晰)
可以提高快门速度
并且焦外的物体也相对虚化的厉害
说了半天废话 看优化技术 MX2的固件。,。。。
正常情况下,应该是2.0,但是手机上个别技术问题,不好说
2.0的好吧~
就这么说,单论光圈的话,F后面的数字越小越好
买台单反就知道了
这是我拿到二妹第二天拍的,也是唯一一个光圈不是2.4的照片,为什么。。。。
(172.74 KB)
点击文件名下载附件
跟着学习了
同一镜头,不同光圈下,锐度这些会有差异,最佳光圈值之外,增大或缩小都可能导致一定程度的劣化,但是不过不是同一镜头,这就不能一概而论了,只能用实际测试来对比,总之不同镜头单靠看光圈值是多少,是无法判断优劣的~
同条件下当然是 光圈越越好
进来学习下
后面那个头最重要。
2.0,一般来说光圈越小,进光量越大。效果越好
类似1/2,1/2.2,1/2.4分母越小,数越大
单纯来说 光圈越大越好,就是F2.0好于F2.2好于F2.4以此类推,这里最容易误会的就是有很多人会看到2.4数字比较大认为就比较好其实不然。但是单纯以光圈大小来说一个镜头的好坏是太片面了
2.0这个数值越小越好
上传的图片不符合要求实木开门2.2和2.0厚的区别是什么?来自:
日分享至 :
我买实木开门的有好多种,有些实木是2.0厚的,有的是2.2厚,2.2厚的比2.0厚的要贵,有什么区别吗?分享至 :
下一篇:上一篇:其它类似问题相关文章相关帖子---实木开门2.2和2.0厚的区别是什么?百度拇指医生
&&&普通咨询
您的网络环境存在异常,
请输入验证码
验证码输入错误,请重新输入1368人阅读
RxJava(5)
为什么翻译这篇文章
ReactiveX 于 发布了正式版RxJava 2.0.0,但到我写本文章为止,还没有发现谁完整的翻译了官方的这篇文档 。
秉着旧事物迟早被新事物替代的想法,于是我用我没过6级的英语咬牙翻译下这篇文章,希望能帮助年轻的司机。但鉴于本人水平有限,翻译得不好,如果各位大神发现哪里写错了,欢迎发邮件通知我,我会在第一时间改正,本人邮箱:
作者: 宇不语
RxJava 2.0 已经按照Reactive-Streams specification规范完全的重写了。2.0 已经独立于RxJava 1.x而存在。
因为Reactive-Streams有一个不同的构架,它改变了一些以往RxJava的用法。这份文档尝试去总结所发生的变化,并描述如何把1.x的代码改写成符合2.x规则的代码。
这个页面是为本库用户写的,这将会有一个分界页面,专门留给为RxJava库开发者以及那些希望为2.x版本开发自定义操作符的用户
Maven 地址和基础包
为了让 RxJava 1.x 和 RxJava 2.x 相互独立,我们把RxJava 2.x 被放在了maven io.reactivex.rxjava2:rxjava:2.x.y 下,类放在了 io.reactivex 包下
用户从 1.x 切换到 2.x 时需要导入的相应的包,但注意不要把1.x和2.x混淆了。
官方2.x的 Java 文档
RxJava 2x 不再支持 null 值,如果传入一个null会抛出 NullPointerException
Observable.just(null);
Single.just(null);
Observable.fromCallable(() -& null)
.subscribe(System.out::println, Throwable::printStackTrace);
Observable.just(1).map(v -& null)
.subscribe(System.out::println, Throwable::printStackTrace);
这意味着 Observable&Void& 不再发射任何值,而只是正常结束或者抛出异常。API 设计者可以定义 Observable&Object& 这样的观察者, 因为并不确定具体是什么类型的 Object。例如,如果你需要一个 signaller-like ,你可以定义一个共享的枚举类型,它是一个单独的实例onNext‘d:
enum Irrelevant { INSTANCE; }
Observable&Object& source = Observable.create((ObservableEmitter&Object& emitter) -& {
System.out.println("Side-effect 1");
emitter.onNext(Irrelevant.INSTANCE);
System.out.println("Side-effect 2");
emitter.onNext(Irrelevant.INSTANCE);
System.out.println("Side-effect 3");
emitter.onNext(Irrelevant.INSTANCE);
source.subscribe(e -& {
}, Throwable::printStackTrace);
Observable 和 Flowable
在RxJava 0.x中关于介绍backpressure部分有一个小小的遗憾,那就是没有用一个单独的类,而是使用了Observable。 主要的背压问题是有很多很火的代码,像UI events,不能合理的背压,导致了无法意料的 MissingBackpressureException。
我们试图在 2.x 中纠正这个问题。因此我们把io.reactivex.Observable 设计成非背压的,并增加一个新的io.reactivex.Flowable 去支持背压。
好消息是操作符的名字几乎没有改动。坏消息是当你执行’organize imports’时必须要格外的小心,它可能无意的给你选择一个非背压的io.reactivex.Observable 。
2.x 的Single类可以发射一个单独onSuccess 或 onError消息。它现在按照Reactive-Streams规范被重新设计,SingleObserver改成了如下的接口。
interface SingleObserver&T& {
void onSubscribe(Disposable d);
void onSuccess(T value);
void onError(Throwable error);
并遵循协议 onSubscribe (onSuccess | onError)?.
Completable
Completable大部分和以前的一样。因为它在1.x的时候就是按照Reactive-Streams的规范进行设计的。
命名上有些变化,
<pletableSubscriber 变成了 pletableObserver 和 onSubscribe(Disposable):
interface CompletableObserver&T& {
void onSubscribe(Disposable d);
void onComplete();
void onError(Throwable error);
并且仍然遵循协议 onSubscribe (onComplete | onError)?.
RxJava 2.0.0-RC2 介绍了一个新的类型 Maybe 。从概念上来说,它是Single 和 Completable 的结合体。它可以发射0个或1个通知或错误的信号。
Maybe类结合了MaybeSource, MaybeObserver&T&作为信号接收接口,同样遵循协议onSubscribe (onSuccess | onError | onComplete)?。因为最多有一个元素被发射,Maybe没有背压的概念。
这意味着调用onSubscribe(Disposable)请求可能还会触发其他 onXXX方法。和Flowable不同,如果那有一个单独的值要发射,那么只有onSuccess被调用,onComplete不被调用。
这个新的类,实际上和其他Flowable的子类操作符一样可以发射0个或1个序列。
Maybe.just(1)
.map(v -& v + 1)
.filter(v -& v == 1)
.defaultIfEmpty(2)
.assertResult(2);
Base reactive interfaces
基础reactive接口
按照Reactive-Streams风格的Flowable实现了 Publisher&T&接口,其他基础类也实现了类似的基础接口
interface ObservableSource&T& {
void subscribe(Observer&? super T& observer);
interface SingleSource&T& {
void subscribe(SingleObserver&? super T& observer);
interface CompletableSource {
void subscribe(CompletableObserver observer);
interface MaybeSource&T& {
void subscribe(MaybeObserver&? super T& observer);
因此,很多操作符需要从用户接收Publisher 和 XSource的一些基础的类型。
Flowable&R& flatMap(Function&? super T, ? extends Publisher&? extends R&& mapper);
Observable&R& flatMap(Function&? super T, ? extends ObservableSource&? extends R&& mapper);
通过Publisher作为输入,你可以组合其他的遵从Reactive-Streams规范的库,而不需要包裹或把它们转换成Flowable。
如果一个操作符必须要提供一个基础类,那么用户将会收到一个完整的基础类。
Flowable&Flowable&Integer&& windows = source.window(5);
pose((Flowable&T& flowable) -&
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()));
Subjects 和 Processors
在Reactive-Streams规范中,Subject类似于行为,即消费者和提供者的事件在同一时间发生。随着Observable/Flowable的分离,支持背压的类都是遵从Reactive-Streams规范的FlowableProcessor&T&的子类。一个关于Subject重要的变化是它们不再支持T -& R这样的转换。
在 2.x 中, io.reactivex.subjects.AsyncSubject, io.reactivex.subjects.BehaviorSubject, io.reactivex.subjects.PublishSubject, io.reactivex.subjects.ReplaySubject 和 io.reactivex.subjects.UnicastSubject 不支持背压。
io.reactivex.processors.AsyncProcessor, io.reactivex.processors.BehaviorProcessor, io.reactivex.processors.PublishProcessor, io.reactivex.processors.ReplayProcessor 和io.reactivex.processors.UnicastProcessor 支持背压。 BehaviorProcessor 和 PublishProcessor 不能协同请求下级的订阅者,如果下游不能保存,则会发射一个MissingBackpressureException异常。其他XProcessor类支持对下游订阅者背压,但是当被订阅源时,它们会无限制的消费。
rx.observables.ConnectableObservable 现在是io.reactivex.observables.ConnectableObservable&T& 和 io.reactivex.flowables.ConnectableFlowable&T&。
GroupedObservable
rx.observables.GroupedObservable 现在是io.reactivex.observables.GroupedObservable&T& 和io.reactivex.flowables.GroupedFlowable&T&.
在1.x中,你可以用GroupedObservable.from()创建一个实例。在2.x中,所有实例都直接继承了GroupedObservable,因此这个工厂方法不再可用; 现在整个类都是抽象的。
不过你可以继承类然后添加你自定义的subscribeActual行为来达到1.x中相似的功能。
class MyGroup&K, V& extends GroupedObservable&K, V& {
final Subject&V&
public MyGroup(K key) {
this.key =
this.subject = PublishSubject.create();
public T getKey() {
protected void subscribeActual(Observer&? super T& observer) {
subject.subscribe(observer);
1.x 和 2.x 是跑在Java 6以上的虚拟机的,所以我们不能使用Java8的功能接口(functional interfaces),比如java.util.function.Function。但我们可以按照这个例子来定义自己的功能接口(functional interfaces)。
一个值得注意的区别是所有的功能接口(functional interfaces)都定义了throws Exception。这对于consumers 和 mappers 来说是一个巨大的便利,你不需要用try-catch捕获异常。
Flowable.just("file.txt")
.map(name -& Files.readLines(name))
.subscribe(lines -& System.out.println(lines.size()), Throwable::printStackTrace);
如果文件不存在或者不可读,结尾的consumer会直接输出IOException。你可以直接调用Files.readLines(name)而不需要捕获异常。
为了减少组件数量,2.x中没有定义Action3-Action9和ActionN。
保留的action接口按照Java 8 functional风格命名。 无参数的Action0 被操作符io.reactivex.functions.Action和Scheduler代替。Action1被重命名为Consumer。Action2 被重命名为BiConsumer。 ActionN 被Consumer&Object[]& 代替。
我们按照Java 8的命名风格定义了io.reactivex.functions.Function 和io.reactivex.functions.BiFunction, 把Func3 - Func9 分别改成了 Function3 - Function9 。FuncN被Function&Object[], R&代替。
此外,操作符不再使用Func1&T, Boolean&但原始返回类型为Predicate&T&。
io.reactivex.functions.Functions类提供了常见的转换功能Function&Object[], R&
Subscriber
Reactive-Streams规范有自己的Subscriber。这个接口是轻量级的,并且把请求管理和取消机制整合进了一个单独的接口org.reactivestreams.Subscription,而不是分别用rx.Producer 和 rx.Subscription。这就可以用比1.x中rx.Subscriber更少的内部状态来创建一个stream consumers。
Flowable.range(1, 10).subscribe(new Subscriber&Integer&() {
public void onSubscribe(Subscription s) {
s.request(Long.MAX_VALUE);
public void onNext(Integer t) {
System.out.println(t);
public void onError(Throwable t) {
t.printStackTrace();
public void onComplete() {
System.out.println("Done");
由于命名冲突,把rx 包改成org.reactivestreams。此外org.reactivestreams.Subscriber 不能从外面添加、取消或请求。
为了弥补这一空缺,我们为Flowable定义了抽象类DefaultSubscriber, ResourceSubscriber 和 DisposableSubscriber 分别提供了类似于rx.Subscriber的资源跟踪支持,并且可以从外面取消 dispose():
ResourceSubscriber&Integer& subscriber = new ResourceSubscriber&Integer&() {
public void onStart() {
request(Long.MAX_VALUE);
public void onNext(Integer t) {
System.out.println(t);
public void onError(Throwable t) {
t.printStackTrace();
public void onComplete() {
System.out.println("Done");
Flowable.range(1, 10).delay(1, TimeUnit.SECONDS).subscribe(subscriber);
subscriber.dispose();
注意,由于Reactive-Streams的兼容性,方法onCompleted被重命名为onComplete。
因为1.x中,Observable.subscribe(Subscriber)返回Subscription,用户经常添加Subscription到CompositeSubscription中,例如:
CompositeSubscription composite = new CompositeSubscription();
composite.add(Observable.range(1, 5).subscribe(new TestSubscriber&Integer&()));
由于Reactive-Streams规范,Publisher.subscribe无返回值。为了弥补这一点,我们增加了E subscribeWith(E subscriber)方法。因为在2.x中ResourceSubscriber 直接实现了Disposable,所以代码可以这样写。
CompositeDisposable composite2 = new CompositeDisposable();
composite2.add(Flowable.range(1, 5).subscribeWith(subscriber));
在onSubscribe/onStart中调用request
注意,在Subscriber.onSubscribe或ResourceSubscriber.onStart中调用request(n)将会立即调用onNext,实例代码如下:
Flowable.range(1, 3).subscribe(new Subscriber&Integer&() {
public void onSubscribe(Subscription s) {
System.out.println("OnSubscribe start");
s.request(Long.MAX_VALUE);
System.out.println("OnSubscribe end");
public void onNext(Integer v) {
System.out.println(v);
public void onError(Throwable e) {
e.printStackTrace();
public void onComplete() {
System.out.println("Done");
This will print:
OnSubscribe start
OnSubscribe end
当你在onSubscribe/onStart中做了一些初始化的工作,而这些工作是在request后面时,会出现一些问题,在onNext执行时,你的初始化工作的那部分代码还没有执行。为了避免这种情况,请确保你调用request时,已经把所有初始化工作做完了。
这个行为不同于1.x中的 request要经过延迟的逻辑直到上游的Producer到达时。在2.x中,总是Subscription先传递下来,90%的情况下没有延迟请求的必要。
Subscription
在RxJava 1.x中,接口rx.Subscription负责流和资源的生命周期管理,即退订和释放资源,例如scheduled tasks。Reactive-Streams规范用这个名称指定source和consumer之间的关系: org.reactivestreams.Subscription 允许从上游请求一个正数,并支持取消。
为了避免名字冲突,1.x的rx.Subscription被改成了 io.reactivex.Disposable。
因为Reactive-Streams的基础接口org.reactivestreams.Publisher 定义subscribe()为无返回值,Flowable.subscribe(Subscriber)不再返回任何Subscription。其他的基础类型也遵循这种规律。
在2.x中其他的subscribe的重载方法返回Disposable。
原始的Subscription容器类型已经被重命名和修改。
CompositeSubscription 改成 CompositeDisposable,
SerialSubscription
和MultipleAssignmentSubscription 被合并到了 SerialDisposable。 set()
方法取消了旧值,而replace()方法没有。
RefCountSubscription 已被删除。
Reactive-Streams规范的操作符支持背压,特别是当它们不发送请求时,它们不会溢出。新的操作符Flowable被设计成适合下游请求,然而这个不意味着MissingBackpressureException不会出现。这个异常仍然存在。但这一次,onNext会抛出这个异常。
作为替代,在2.x中Observable完全不支持背压,但可以被替换。
Reactive-Streams compliance
Flowable-based sources和operators是遵从Reactive-Streams 1.0.0规范的,除了一个规则§3.9和解释的规则§1.3:
§3.9: While the Subscription is not cancelled, Subscription.request(long n) MUST signal onError with a java.lang.IllegalArgumentException if the argument is &= 0. The cause message MUST include a reference to this rule and/or quote the full rule.
Rule §3.9 requires excessive overhead to handle (half-serializer on every operator dealing with request()) for a bug-case. RxJava 2 (and Reactor 3 in fact) reports the IllegalArgumentException to RxJavaPlugins.onError and ignores it otherwise. RxJava 2 passes the Test Compatibility Kit (TCK) by applying a
that routes the IllegalArgumentException into the Subscriber.onError in an async-safe manner. All major Reactive-Streams libraries are free o Reactor 3 ignores it as we do and Akka-Stream uses a converter (to interact with other RS sources and consumers) which has (probably) a similar routing behavior as our TCK operator.
§1.3: onSubscribe, onNext, onError and onComplete signaled to a Subscriber MUST be signaled sequentially (no concurrent notifications).
TCK 允许同步但限制onSubscribe 和 onNext之间往返。也就是说在onSubscribe中,调用request(1)后将会调用onNext,在onNext返回后request(1)才会返回。虽然大部分操作符都是这样的,但操作符observeOn会异步的调用onNext,因此onSubscribe会和onNext同时被调用。这就是由TCK来检测,我们使用来延迟下游请求直到onSubscribe返回。再次声明,这种异步行为不是RxJava 2的一个问题,因为在Reactor 3中操作符是线程安全的执行onSubscribe。Akka-Stream的转换类似于延迟请求。
因为这两个影响inter-library的行为,我们考虑在以后给Flowable增加了一个标准的操作符,把这两种行为改到一个单独的方法。
2.x 中重新设计了RxJavaPlugins类,现在支持运行时改变回调。测试需要重写schedulers,生命周期方法可以通过回调函数。
RxJavaObservableHook和友类现在都取消了,RxJavaHooks功能被加入到了RxJavaPlugins。
Schedulers
在2.x的API中仍然支持主要的默认scheduler: computation, io, newThread 和 trampoline,可以通过io.reactivex.schedulers.Schedulers这个实用的工具类来调度。
2.x中不存在immediate 调度器。 它被频繁的误用,并没有正常的实现 Scheduler 规范;它包含用于延迟动作的阻塞睡眠,并且不支持递归调度。你可以使用Schedulers.trampoline()来代替它。
Schedulers.test()已经被移除,这样避免了默认调度器休息的概念差异。那些返回一个”global”的调度器实例是鉴于test()总是返回一个新的TestScheduler实例。现在我们鼓励测试人员使用这样简单的代码new TestScheduler()。
io.reactivex.Scheduler抽象类现在支持直接调度任务,不需要先创建然后通过Worker调度。
public abstract class Scheduler {
public Disposable scheduleDirect(Runnable task) { ... }
public Disposable scheduleDirect(Runnable task, long delay, TimeUnit unit) { ... }
public Disposable scheduleDirectPeriodically(Runnable task, long initialDelay,
long period, TimeUnit unit) { ... }
public long now(TimeUnit unit) { ... }
主要的目的是为了避免跟踪Worker的开销。方法有一个默认的实现,你可以直接复用 createWorker ,但如果有需要,你也可以重写它来实现更强大的功能。
这些方法返回了当前时间调度器的概念, now()被改成接受一个用于指定单位量的TimeUnit的方法。
进入reactive的世界
RxJava 1.x的设计缺陷之一是暴露了rx.Observable.create()方法,该方法虽然很强大,但导致了你很少使用内置典型的操作符。不幸的是,有太多的代码依赖于这个库,所以我们不能删除或重命名它。
2.x是一个新的开始,我们不会再犯这个错误了。每一个基础类Flowable, Observable, Single, Maybe 和 Completable 都有安全的create操作符去支持背压和取消。
Flowable.create((FlowableEmitter&Integer& emitter) -& {
emitter.onNext(1);
emitter.onNext(2);
emitter.onComplete();
}, BackpressureStrategy.BUFFER);
实际上,1.x中fromEmitter已经被重命名为Flowable.create。其他基础类型也有类似的create方法。
离开reactive的世界
除了subscribing 各自的consumers(Subscriber, Observer, SingleObserver, MaybeObserver 和 CompletableObserver) 以及functional-interface 基础consumers(例如 subscribe(Consumer&T&, Consumer&Throwable&, Action)),以前在1.x中独立的BlockingObservable 已经集成了主要的基础类型。现在你可以直接调用blockingX来阻塞等待结果:
List&Integer& list = Flowable.range(1, 100).toList().blockingGet();
Integer i = Flowable.range(100, 100).blockingLast();
在2.x中另外一个关于rx.Subscriber 和org.reactivestreams.Subscriber重要的区别是,你的Subscriber和Observer不允许抛出任何致命的异常。这意味着下面这样的代码不再是合法的:
Subscriber&Integer& subscriber = new Subscriber&Integer&() {
public void onSubscribe(Subscription s) {
s.request(Long.MAX_VALUE);
public void onNext(Integer t) {
if (t == 1) {
throw new IllegalArgumentException();
public void onError(Throwable e) {
if (e instanceof IllegalArgumentException) {
throw new UnsupportedOperationException();
public void onComplete() {
throw new NoSuchElementException();
Flowable.just(1).subscribe(subscriber);
这样的规则同样适用于Observer, SingleObserver, MaybeObserver 和 CompletableObserver。
由于很多现有基于1.x的代码做了类似的事情,我们设计了safeSubscribe方法来帮助你处理这样的代码。
当然你也可以使用subscribe(Consumer&T&, Consumer&Throwable&, Action)方法来提供一个回调。
Flowable.just(1)
.subscribe(
subscriber::onNext,
subscriber::onError,
subscriber::onComplete,
subscriber::onSubscribe
测试RxJava 2.x和1.x中一样,Flowable可以用io.reactivex.subscribers.TestSubscriber测试,而非背压的Observable, Single, Maybe 和 Completable可以用io.reactivex.observers.TestObserver测试。
test() “operator”
为了支持我们内部测试,所有的基础类都有 test() 方法,返回TestSubscriber 或 TestObserver:
TestSubscriber&Integer& ts = Flowable.range(1, 5).test();
TestObserver&Integer& to = Observable.range(1, 5).test();
TestObserver&Integer& tso = Single.just(1).test();
TestObserver&Integer& tmo = Maybe.just(1).test();
TestObserver&Integer& tco = plete().test();
第二个便利之处在于,大部分TestSubscriber/TestObserver方法返回自身实例,这让我们可以链式调用各种assertX方法。第三个便利是,你可以流畅的测试你的代码而不需要去创建或者引入TestSubscriber/TestObserver实例。
Flowable.range(1, 5)
.assertResult(1, 2, 3, 4, 5)
值得注意的新的断言方法
assertResult(T... items): 断言在onComplete中将会按指定顺序收到给定的值,并且没有错误。
assertFailure(Class&? extends Throwable& clazz, T... items): 断言将会收到指定的异常。
assertFailureAndMessage(Class&? extends Throwable& clazz, String message, T... items): 和assertFailure一样,但还会验证 getMessage() 中包含的值。
awaitDone(long time, TimeUnit unit) 等待一个终结事件,如果超时了,将会取消该事件。
assertOf(Consumer&TestSubscriber&T&& consumer) 组成一些断言到流式链中。
其中一个好处是,把Flowable改为Observable,所以测试代码不需要改变,内部的已经把TestSubscriber改成了TestObserver。
提前取消和请求
TestObserver中的test()方法有一个 test(boolean cancel) 重载,它能在订阅前取消TestSubscriber/TestObserver:
PublishSubject&Integer& pp = PublishSubject.create();
assertFalse(pp.hasSubscribers());
pp.test(true);
assertFalse(pp.hasSubscribers());
TestSubscriber 有 test(long initialRequest) 和 test(long initialRequest, boolean cancel) 重载,用于指定初始请求数量以及TestSubscriber是否应该立即被取消。如果initialRequest被给定,TestSubscriber 实例通常需要被捕获以便访问request()方法:
PublishProcessor&Integer& pp = PublishProcessor.create();
TestSubscriber&Integer& ts = pp.test(0L);
ts.request(1);
pp.onNext(1);
pp.onNext(2);
ts.assertFailure(MissingBackpressureException.class, 1);
测试异步代码
对于给定的异步代码,流畅的阻塞终端事件是可能的:
Flowable.just(1)
.subscribeOn(Schedulers.single())
.awaitDone(5, TimeUnit.SECONDS)
.assertResult(1);
Mockito & TestSubscriber
那些在1.x中正在使用Mockito和Observer的用户需要去使用Subscriber.onSubscribe方法去提出初始的请求,否则序列化将会挂起或者失败:
@SuppressWarnings("unchecked")
public static &T& Subscriber&T& mockSubscriber() {
Subscriber&T& w = mock(Subscriber.class);
Mockito.doAnswer(new Answer&Object&() {
public Object answer(InvocationOnMock a) throws Throwable {
Subscription s = a.getArgumentAt(0, Subscription.class);
s.request(Long.MAX_VALUE);
return null;
}).when(w).onSubscribe((Subscription)any());
操作符的差别
2.x中大部分操作符仍然被保留,实际上大部分行为和1.x一样。下面的列表中列出了每一个基础类的在1.x和2.x的区别
通常来说,很多操作符提供了重载,允许指定运行上游的内部缓冲区的大小或者预先分配的数量。
一些操作符重载已经被重命名为了后缀风格,比如 fromArray, fromIterable。这么做的原因是,当用Java 8编译时,javac往往不能区分功能接口类型。
在1.x中被标记为@Beta 或 @Experimental的操作符已经成为正式操作符了。
1.x Observable 到 2.x Flowable
添加 amb(ObservableSource...) 重载, 2-9 参数被删除
RxRingBuffer.SIZE
bufferSize()
combineLatest
增加条目重载, 增加 带bufferSize 参数的重载, combineLatest(List) 被删除
增加带 prefetch 参数的重载, 5-9 重载被删除 , 使用 concatArray 代替
增加 concatArray 和 concatArrayDelayError
增加 concatArrayEager 和 concatArrayEagerDelayError
concatDelayError
增加带延时的重载
concatEagerDelayError
增加带延时的重载
create(SyncOnSubscribe)
被 generate + 重载代替
create(AsnycOnSubscribe)
create(OnSubscribe)
使用安全的 create(FlowableOnSubscribe, BackpressureStrategy), 支持 unsafeCreate()
拆分成 fromArray, fromIterable, fromFuture
增加 fromPublisher
重命名为 create()
增加 intervalRange()
被删除, 使用 take
增加带 prefetch的重载
mergeDelayError
增加带 prefetch的重载
sequenceEqual
增加带 bufferSize的重载
switchOnNext
增加带 prefetch的重载
switchOnNextDelayError
增加带 prefetch的重载
增加带 bufferSize 和 delayErrors
的重载, 拆分成了 zipArray 和 zipIterable
RC3 返回 Single&Boolean&
RC3 返回 Single&Boolean&
asObservable
重命名为 hide(), 隐藏所有的身份
重载自定义的 Collection 提供者
cache(int)
RC3 返回 Single&U&
collect(U, Action2&U, T&)
改成 collectInto 和 RC3 返回 Single&U&
增加带 prefetch 的重载
concatMapDelayError
增加带 prefetch的重载, 支持延时
concatMapEager
增加带 prefetch的重载
concatMapEagerDelayError
增加带 prefetch的重载,
RC3 返回 Single&Long&
被删除, 使用 count
重载自定义的 Collection 提供者.
doOnCompleted
重命名为 doOnComplete
doOnUnsubscribe
重命名为 Flowable.doOnCancel 和 doOnDispose ,
增加 doOnLifecylce 来处理 onSubscribe, request 和 cancel
elementAt(int)
RC3 不再发射 NoSuchElementException 如果源比索引更小
elementAt(Func1, int)
被删除, 使用 filter(predicate).elementAt(int) 代替
elementAtOrDefault(int, T)
重命名为 elementAt(int, T) 和 RC3 返回 Single&T&
elementAtOrDefault(Func1, int, T)
被删除, 使用 filter(predicate).elementAt(int, T) 代替
RC3 重命名为 firstElement 返回 Maybe&T&
first(Func1)
被删除, 使用 filter(predicate).first()代替
firstOrDefault(T)
重命名为 first(T)
RC3 返回 Single&T&
firstOrDefault(Func1, T)
被删除, 使用 filter(predicate).first(T)代替
增加带 prefetch的重载
增加 forEachWhile(Predicate&T&, [Consumer&Throwable&, [Action]]) 用于有条件停止 consumption
增加带 bufferSize和 delayError的重载, 支持 支持内部自定义map,RC1中没有
ignoreElements
RC3 返回 Completable
RC3 返回 Single&Boolean&
RC3 重命名为 lastElement 返回 Maybe&T&
last(Func1)
被删除, 使用 filter(predicate).last()代替
lastOrDefault(T)
重命名为 last(T) RC3 返回 Single&T&
lastOrDefault(Func1, T)
被删除, 使用 filter(predicate).last(T)代替
被删除, 使用 just代替
publish(Func1)
增加带 prefetch的重载
reduce(Func2)
RC3 返回 Maybe&T&
增加 reduceWith(Callable, BiFunction) 为了减少自定义Subscriber, 返回 Single&T&
增加 repeatUntil(BooleanSupplier)
repeatWhen(Func1, Scheduler)
删除了重载, 使用 subscribeOn(Scheduler).repeatWhen(Function) 代替
增加 retry(Predicate), retry(int, Predicate)
增加 retryUntil(BooleanSupplier)
retryWhen(Func1, Scheduler)
删除了重载, 使用 subscribeOn(Scheduler).retryWhen(Function) 代替
增加 sampleWith(Callable, BiFunction) 去扫描自定义的Subscriber方式
RC3 重命名为 singleElement 返回 Maybe&T&
single(Func1)
被删除,使用 filter(predicate).single()代替
singleOrDefault(T)
重命名为 single(T) RC3 返回 Single&T&
singleOrDefault(Func1, T)
被删除,使用 filter(predicate).single(T)代替
增加带 bufferSize 和 delayError 的重载
2-9 参数的被删除了, 使用 startWithArray 代替
增加 startWithArray 来减少二义性
增加 subscribeWith 返回输入的订阅对象
增加带 prefetch 的重载
switchMapDelayError
增加带 prefetch 的重载
takeLastBuffer
增加 test()
timeout(Func0&Observable&, ...)
方法签名改成了 timeout(Publisher, ...) 删除了方法, 如果有需要,使用 defer(Callable&Publisher&&)
toBlocking().y
内联 blockingY() 操作符, 除了 toFuture
toCompletable
RC3 被删除, 使用 ignoreElements代替
RC3 返回 Single&List&T&&
RC3 返回 Single&Map&K, V&&
toMultimap
RC3 返回 Single&Map&K, Collection&V&&&
增加 toFuture
增加 toObservable
RC3 被删除, 使用 single(T)代替
toSortedList
RC3 增加 Single&List&T&&
withLatestFrom
5-9 个参数的重载被删除
增加带 prefetch 和 delayErrors 的重载
不同的返回类型
2.x中一些的操作符产生确切的一个值或者一个错误时,返回Single。
all(Predicate)
Observable&Boolean&
Single&Boolean&
如果所有的元素都匹配,则发射true
any(Predicate)
Observable&Boolean&
Single&Boolean&
如果所有的元素都匹配,则发射true
Observable&Long&
Single&Long&
计算序列中元素的数量
elementAt(int)
Observable&T&
Emits 给定位置处的元素或完成的元素
elementAt(int, T)
Observable&T&
发射指定位置的元素或默认元素
Observable&T&
发射第一个元素或者抛出 NoSuchElementException
firstElement()
Observable&T&
发射第一个元素或者结束
ignoreElements()
Observable&T&
Completable
忽略所有非终端事件
Observable&Boolean&
Single&Boolean&
如果源为空,则发射true
Observable&T&
发射最后一个元素或默认值
lastElement()
Observable&T&
发射最后一个元素或结束
reduce(BiFunction)
Observable&T&
发射减少的值或者结束
reduce(Callable, BiFunction)
Observable&U&
发射减少的值或者初始的值
reduceWith(U, BiFunction)
Observable&U&
发射减少的值或者初始的值
Observable&T&
发射唯一的元素或默认值
singleElement()
Observable&T&
发射唯一的元素或结束
Observable&List&T&&
Single&List&T&&
将所有元素放到 List
Observable&Map&K, V&&
Single&Map&K, V&&
将所有元素放到 Map
toMultimap()
Observable&Map&K, Collection&V&&&
Single&Map&K, Collection&V&&&
将所有元素包装到Collection后放到 Map
toSortedList()
Observable&List&T&&
Single&List&T&&
将所有元素放到 List 并排序
为了保证最终的2.0API尽可能干净,我们删除了一些候选的方法和组件。
删除时的版本
Flowable.toCompletable()
使用 Flowable.ignoreElements()代替
Flowable.toSingle()
使用 Flowable.single(T)代替
Flowable.toMaybe()
使用 Flowable.singleElement()代替
Observable.toCompletable()
使用 Observable.ignoreElements()代替
Observable.toSingle()
使用 Observable.single(T)代替
Observable.toMaybe()
使用 Observable.singleElement()代替
doOnCancel/doOnDispose/unsubscribeOn
在1.x中,doOnUnsubscribe总是执行终端事件,因为SafeSubscriber调用了unsubscribe。这实际上是没有必要的。Reactive-Streams规范中,一个终端事件到达Subscriber,上游的Subscription会取消,因此调用 cancel()是一个空操作。
由于同样的原因unsubscribeOn也没被在终端路径上调用,但只有实际在链上调用cancel时,才会调用unsubscribeOn。
因此,下面的序列不会被调用
doOnCancel:
Flowable.just(1, 2, 3)
.doOnCancel(() -& System.out.println("Cancelled!"))
.subscribe(System.out::println);
然而,下面将会调用take操作符在传送过程中取消onNext
Flowable.just(1, 2, 3)
.doOnCancel(() -& System.out.println("Cancelled!"))
.subscribe(System.out::println);
如果你需要在终端或者取消时执行清理,考虑使用using操作符代替。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:7319次
排名:千里之外
原创:50篇
评论:16条
(2)(5)(6)(11)(8)(17)(3)}

我要回帖

更多关于 神魔之战2.0.2攻略 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信