Observable.from(需要在另一个线程上完成的事情)

时间:2015-03-02 10:54:05

标签: java rx-java

我正在学习Rx-java并遇到一个小问题。 我试图获取一个Object列表并将其传递给Observable.from(),以便我可以使用它。

问题:这个列表需要在另一个线程上进行(内部的http调用),所以Observable.from(getList())什么也没给我。

我尝试过这样的事情:

Observable.create(new Observable.OnSubscribe>(){       @覆盖       public void call(Subscriber> subscriber){         subscriber.onNext(的GetList());         subscriber.onCompleted();       }     订阅...

但是这个订阅了Iterable,onNext只传递完整列表而不是列表中的每个OIbject。 我错过了什么?我怎么做 ? 感谢

更新

以下是我尝试做的事情(以及我如何使用toSortedList):

Observable.from(getList())
    .subscribeOn(Schedulers.newThread())
    .observeOn(AndroidSchedulers.mainThread())
    .toSortedList(new Func2<Object, Object, Integer>() {
      @Override
      public Integer call(Object left, Object right) {
        if (left.equals(right))
          return 0;
        return left.getLabel(pm).compareToIgnoreCase(right.getLabel(pm));
      }
    })
    .subscribe(new Observer<List<Object>>() {
//On next sends a List of objects I'm using
}

问题是需要在另一个Thread上调用getList()(它返回一个Iterable,而不是一个Observable)。 也许我没有正确地使用你的第一个解决方案dwursteisen。

更新2

这是我不明白为什么它不起作用的事情:

Observable.just(0)
    .subscribeOn(Schedulers.newThread())
    .observeOn(AndroidSchedulers.mainThread())
    .flatMap(new Func1<Integer, Observable<Object>>() {
      @Override
      public Observable<Object> call(Integer integer) {
        return Observable.from(getList());
      }
    })
    .toSortedList(new Func2<Object, Object, Integer>() {
      @Override
      public Integer call(Object left, Object right) {
        if (left.equals(right))
          return 0;
        return left.getLabel(pm).compareToIgnoreCase(right.getLabel(pm));
      }
    })
    .subscribe( ... )

或者通过订阅替换flatMap调用并在onNext中执行所有操作,它仍然在mainThread上调用getList()...

2 个答案:

答案 0 :(得分:2)

如果您想使用特定线程,可以使用subscribeOn方法指定要使用的“tread”(调度程序)。

sourceObservable.subscribeOn(httpScheduler)
                .flatMap(Observable::from)
                .subscribe();

如果它不起作用,您仍然可以使用您的解决方案。但只需迭代你的清单:

Observable.create(new Observable.OnSubscribe<CategorizedActivityInfoWrapper>() {
  @Override
  public void call(Subscriber<? super CategorizedActivityInfoWrapper> subscriber) {
     for(o : getList()) {
         subscriber.onNext(o);
     }

     subscriber.onCompleted();
  }
}).subscribe ...

<强>更新

Observable.from(getList()).subscribe();

也可以这样写:

    List objs = getList();
    Observable.from(objs).subscribe();

因此,getList()将在当前线程中调用。您将无法控制将调用哪个线程getList()

答案 1 :(得分:0)

您需要在observeOn之前(以及可选地在subscribeOn之后)执行异步计算:

public class AsyncStartOtherThread {
    public static void main(String[] args) throws Exception {
        CountDownLatch cdl = new CountDownLatch(1);
        Observable.just(1).subscribeOn(Schedulers.newThread())
        .map(e -> {
            System.out.println(Thread.currentThread());
            return Arrays.asList(1, 2, 3, 4, 5);
        })
        .observeOn(Schedulers.computation())
        .doOnNext(e -> System.out.println(Thread.currentThread()))
        .flatMap(Observable::from)
        .toSortedList((a, b) -> Integer.compare(b, a))
        .subscribe(System.out::println, Throwable::printStackTrace, () -> { System.out.println("Done"); cdl.countDown(); });
        ;
        cdl.await();
    }
}