@Override
    public void request(long n) {
      if (once) {
        return;
      }
      if (n < 0L) {
        throw new IllegalStateException("n >= required but it was " + n);
      }
      if (n != 0L) {
        once = true;
        Subscriber<? super T> a = actual;
        if (a.isUnsubscribed()) {
          return;
        }
        T v = value;
        try {
          a.onNext(v);
        } catch (Throwable e) {
          Exceptions.throwOrReport(e, a, v);
          return;
        }

        if (a.isUnsubscribed()) {
          return;
        }
        a.onCompleted();
      }
    }
  @Test
  public void onErrorSuccessWithUnsubscribeFailure() {
    AtomicReference<Throwable> onError = new AtomicReference<Throwable>();
    Subscriber<String> o = OBSERVER_SUCCESS(onError);
    try {
      o.add(
          Subscriptions.create(
              new Action0() {

                @Override
                public void call() {
                  // break contract by throwing exception
                  throw new SafeObserverTestException("failure from unsubscribe");
                }
              }));
      new SafeSubscriber<String>(o).onError(new SafeObserverTestException("failed"));
      fail("we expect the unsubscribe failure to cause an exception to be thrown");
    } catch (Exception e) {
      e.printStackTrace();

      assertTrue(o.isUnsubscribed());

      // we still expect onError to have received something before unsubscribe blew up
      assertNotNull(onError.get());
      assertTrue(onError.get() instanceof SafeObserverTestException);
      assertEquals("failed", onError.get().getMessage());

      // now assert the exception that was thrown
      assertTrue(e instanceof SafeObserverTestException);
      assertEquals("failure from unsubscribe", e.getMessage());
    }
  }
  @Test
  public void onCompleteSuccessWithUnsubscribeFailure() {
    Subscriber<String> o = OBSERVER_SUCCESS();
    try {
      o.add(
          Subscriptions.create(
              new Action0() {

                @Override
                public void call() {
                  // break contract by throwing exception
                  throw new SafeObserverTestException("failure from unsubscribe");
                }
              }));
      new SafeSubscriber<String>(o).onCompleted();
      fail("expects exception to be thrown");
    } catch (Exception e) {
      e.printStackTrace();

      assertTrue(o.isUnsubscribed());

      assertTrue(e instanceof SafeObserverTestException);
      assertEquals("failure from unsubscribe", e.getMessage());
      // expected since onError fails so SafeObserver can't help
    }
  }
Beispiel #4
0
 @Override
 public void call(Subscriber<? super Long> op) {
   long l = 1;
   while (!op.isUnsubscribed()) {
     op.onNext(l++);
   }
   op.onCompleted();
 }
 @Override
 public void call() {
   Subscriber<? super T> a = actual;
   if (a.isUnsubscribed()) {
     return;
   }
   T v = value;
   try {
     a.onNext(v);
   } catch (Throwable e) {
     Exceptions.throwOrReport(e, a, v);
     return;
   }
   if (a.isUnsubscribed()) {
     return;
   }
   a.onCompleted();
 }
 @Override
 public void onPreviewFrame(byte[] data) {
   if (subscriber != null && !subscriber.isUnsubscribed() && rxCamera.isOpenCamera()) {
     if (data == null || data.length == 0) {
       subscriber.onError(new CameraDataNullException());
     }
     RxCameraData rxCameraData = new RxCameraData();
     rxCameraData.cameraData = data;
     rxCameraData.rotateMatrix = rxCamera.getRotateMatrix();
     subscriber.onNext(rxCameraData);
   }
 }
Beispiel #7
0
  private static void produceValuesAndAnError(Subscriber s) {
    Subscriber subscriber = (Subscriber) s;

    try {
      for (int ii = 0; ii < 50; ii++) {
        if (!subscriber.isUnsubscribed()) {
          subscriber.onNext("Pushed value " + ii);
        }

        if (ii == 5) {
          throw new Throwable("Something has gone wrong here");
        }
      }

      if (!subscriber.isUnsubscribed()) {
        subscriber.onCompleted();
      }

    } catch (Throwable throwable) {
      subscriber.onError(throwable);
    }
  }
  @Test
  public void onErrorFailureWithUnsubscribeFailure() {
    Subscriber<String> o = OBSERVER_ONERROR_FAIL();
    try {
      o.add(
          Subscriptions.create(
              new Action0() {

                @Override
                public void call() {
                  // break contract by throwing exception
                  throw new SafeObserverTestException("failure from unsubscribe");
                }
              }));
      new SafeSubscriber<String>(o).onError(new SafeObserverTestException("onError failure"));
      fail("expects exception to be thrown");
    } catch (Exception e) {
      e.printStackTrace();

      assertTrue(o.isUnsubscribed());

      // assertions for what is expected for the actual failure propagated to onError which then
      // fails
      assertTrue(e instanceof RuntimeException);
      assertEquals(
          "Error occurred when trying to propagate error to Observer.onError and during unsubscription.",
          e.getMessage());

      Throwable e2 = e.getCause();
      assertTrue(e2 instanceof CompositeException);
      assertEquals(
          "Chain of Causes for CompositeException In Order Received =>",
          e2.getCause().getMessage());

      Throwable e3 = e2.getCause();
      assertTrue(e3.getCause() instanceof SafeObserverTestException);
      assertEquals("onError failure", e3.getCause().getMessage());

      Throwable e4 = e3.getCause();
      assertTrue(e4.getCause() instanceof SafeObserverTestException);
      assertEquals("onErrorFail", e4.getCause().getMessage());

      Throwable e5 = e4.getCause();
      assertTrue(e5.getCause() instanceof SafeObserverTestException);
      assertEquals("failure from unsubscribe", e5.getCause().getMessage());
    }
  }
Beispiel #9
0
  private void init() {
    // AndroidRx 再探
    File[] folders = new File[5];
    Observable.from(folders)
        .flatMap(
            new Func1<File, Observable<File>>() {
              @Override
              public Observable<File> call(File file) {
                return Observable.from(file.listFiles());
              }
            })
        .filter(
            new Func1<File, Boolean>() {
              @Override
              public Boolean call(File file) {
                return file.getName().endsWith(".png");
              }
            })
        .map(
            new Func1<File, Bitmap>() {
              @Override
              public Bitmap call(File file) {
                return getBitmapFromFile(file);
              }
            })
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(
            new Action1<Bitmap>() {
              @Override
              public void call(Bitmap bitmap) {
                // 主线程处理
              }
            });

    Observer<String> observer =
        new Observer<String>() {
          @Override
          public void onCompleted() {}

          @Override
          public void onError(Throwable e) {}

          @Override
          public void onNext(String s) {}
        };

    // Observer 扩展类 Subscriber
    // 区别 onStart()
    Subscriber<String> subscriber =
        new Subscriber<String>() {
          @Override
          public void onStart() {
            super.onStart();
          }

          @Override
          public void onCompleted() {}

          @Override
          public void onError(Throwable e) {}

          @Override
          public void onNext(String s) {}
        };
    subscriber.isUnsubscribed(); // 是否取消订阅
    subscriber.unsubscribe(); // 取消订阅

    Observable<String> observable =
        Observable.create(
            new Observable.OnSubscribe<String>() {
              @Override
              public void call(Subscriber<? super String> subscriber) {
                subscriber.onStart();
                subscriber.onNext("Hello");
                subscriber.onNext("Hi");
                subscriber.onCompleted();
              }
            });
    observable.subscribe(observer); // 订阅
    observable.subscribe(subscriber); // 同上,类似监听点击事件

    // 应用一:
    Observable.just(0, 1, 2, 3)
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(
            new Action1<Integer>() {
              @Override
              public void call(Integer integer) {
                LogUtil.d(String.valueOf(integer));
              }
            });

    // 应用二:
    Observable.just(0)
        .map(
            new Func1<Integer, Drawable>() {
              @TargetApi(Build.VERSION_CODES.LOLLIPOP)
              @Override
              public Drawable call(Integer integer) {
                return getTheme().getDrawable(integer);
              }
            })
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(
            new Observer<Drawable>() {
              @Override
              public void onCompleted() {}

              @Override
              public void onError(Throwable e) {
                ToastManager.show(getBaseContext(), e.getMessage());
              }

              @Override
              public void onNext(Drawable drawable) {
                // TODO 显示内容
              }
            });

    RxView.clickEvents(null)
        .throttleFirst(500, TimeUnit.MILLISECONDS) // 防抖动
        .subscribe(
            new Action1<ViewClickEvent>() {
              @Override
              public void call(ViewClickEvent viewClickEvent) {}
            });
  }
  void emitLoop() {
    final Subscriber<? super T> c = child;

    outer:
    for (; ; ) {
      long localRequested;
      Producer localProducer;
      Object localTerminal;
      List<T> q;
      synchronized (this) {
        localRequested = missedRequested;
        localProducer = missedProducer;
        localTerminal = missedTerminal;
        q = queue;
        if (localRequested == 0L && localProducer == null && q == null && localTerminal == null) {
          emitting = false;
          return;
        }
        missedRequested = 0L;
        missedProducer = null;
        queue = null;
        missedTerminal = null;
      }
      boolean empty = q == null || q.isEmpty();
      if (localTerminal != null) {
        if (localTerminal != Boolean.TRUE) {
          c.onError((Throwable) localTerminal);
          return;
        } else if (empty) {
          c.onCompleted();
          return;
        }
      }
      long e = 0;
      if (q != null) {
        for (T v : q) {
          if (c.isUnsubscribed()) {
            return;
          } else if (hasError) {
            continue outer; // if an error has been set, shortcut the loop and act on it
          }
          try {
            c.onNext(v);
          } catch (Throwable ex) {
            Exceptions.throwOrReport(ex, c, v);
            return;
          }
        }
        e += q.size();
      }
      long r = requested;
      // if requested is max, we don't do any accounting
      if (r != Long.MAX_VALUE) {
        // if there were missing requested, add it up
        if (localRequested != 0L) {
          long u = r + localRequested;
          if (u < 0) {
            u = Long.MAX_VALUE;
          }
          r = u;
        }
        // if there were emissions and we don't run on max since the last check, subtract
        if (e != 0L && r != Long.MAX_VALUE) {
          long u = r - e;
          if (u < 0) {
            throw new IllegalStateException("More produced than requested");
          }
          r = u;
        }
        requested = r;
      }
      if (localProducer != null) {
        if (localProducer == NULL_PRODUCER) {
          currentProducer = null;
        } else {
          currentProducer = localProducer;
          if (r != 0L) {
            localProducer.request(r);
          }
        }
      } else {
        Producer p = currentProducer;
        if (p != null && localRequested != 0L) {
          p.request(localRequested);
        }
      }
    }
  }
    protected void drain() {
      synchronized (this) {
        if (emitting) {
          missedEmitting++;
          return;
        }
        emitting = true;
        missedEmitting = 0;
      }
      final List<SourceSubscriber<T>.MergeItemSubscriber> subs = subscribers;
      final Subscriber<T> child = s;
      Object[] active = new Object[subs.size()];
      do {
        long r;

        outer:
        while ((r = requested) > 0) {
          int idx = lastIndex;
          synchronized (subs) {
            if (subs.size() == active.length) {
              active = subs.toArray(active);
            } else {
              active = subs.toArray();
            }
          }

          int resumeIndex = 0;
          int j = 0;
          for (Object o : active) {
            @SuppressWarnings("unchecked")
            MergeItemSubscriber e = (MergeItemSubscriber) o;
            if (e.index == idx) {
              resumeIndex = j;
              break;
            }
            j++;
          }
          int sumConsumed = 0;
          for (int i = 0; i < active.length; i++) {
            j = (i + resumeIndex) % active.length;

            @SuppressWarnings("unchecked")
            final MergeItemSubscriber e = (MergeItemSubscriber) active[j];
            final RxRingBuffer b = e.buffer;
            lastIndex = e.index;

            if (!e.once && b.peek() == null) {
              subs.remove(e);

              synchronized (guard) {
                this.active--;
              }
              csub.remove(e);

              e.release();

              subscribeNext();

              WIP.decrementAndGet(this);

              continue outer;
            }

            int consumed = 0;
            Object v;
            while (r > 0 && (v = b.poll()) != null) {
              nl.accept(child, v);
              if (child.isUnsubscribed()) {
                return;
              }
              r--;
              consumed++;
            }
            if (consumed > 0) {
              sumConsumed += consumed;
              REQUESTED.addAndGet(this, -consumed);
              e.requestMore(consumed);
            }
            if (r == 0) {
              break outer;
            }
          }
          if (sumConsumed == 0) {
            break;
          }
        }

        if (active.length == 0) {
          if (wip == 0) {
            child.onCompleted();
            return;
          }
        }
        synchronized (this) {
          if (missedEmitting == 0) {
            emitting = false;
            break;
          }
          missedEmitting = 0;
        }
      } while (true);
    }