使用Android上的RxJava以定期间隔发出UI中的绘图对象

Oli*_*ler 1 android rx-java

我在Observable中解析SVG文件.在解析XML时,点作为"Path"对象发出.解析发生在一个单独的线程中,我想逐点绘制SVG文件.换句话说,我想逐个向UI发射点,例如每50毫秒一个.

private void drawPath(final String chars) {

    Observable.create(new Observable.OnSubscribe<Path>() {

        @Override public void call(Subscriber<? super Path> subscriber) {
            try {

                while ([omitted]) {

                    // omitted: a lot of processing
                    // an XML path from an SVG file is parsed into an Android path to be drawn on a canvas
                    // this happens point by point

                    subscriber.onNext(path); // emit path point by point as the XML is processed
                }
            }
                subscriber.onCompleted();
            } catch (Exception e) {
                subscriber.onError(e);
            }
        }

    }).buffer(50, TimeUnit.MILLISECONDS, 1) // delay each point so the UI can process it and is not overwhelmed
            .subscribeOn(Schedulers.newThread()).observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Action1<List<Path>>() {

                @Override public void call(List<Path> paths) {
                    System.out.println("**** SVG Parser: drawPath on UI thread");

                    if (paths.size() > 0) { drawPath(paths.get(0), paint); }

                }

            }, new Action1<Throwable>() {

                @Override public void call(Throwable throwable) {
                    throwable.printStackTrace(); // ignore silently
                }

            });

}
Run Code Online (Sandbox Code Playgroud)

当我使用.buffer()时,每个Path都会在生成后立即发出..buffer()似乎没有在这里做任何事情.

我试过.throttle(),但后来省略了点.

我怎样才能做到这一点?

BTW:这里没有背压问题,因为解析的SVG文件是有限的.我只想在一个单独的线程中解析它,缓冲结果并缓慢发出它们.

a.b*_*cci 5

您需要使用.zip()运算符.timer().来自原始的RxJava wiki:

  • zip():

    通过指定的函数将Observable组合在一起,并根据此函数的结果发出项目

  • timer():

    创建一个在给定延迟后发出单个项目的Observable

所以,如果你使用zip()你原来的结合Observertimer(),你可以延迟每个输出Path每50毫秒:

private void drawPath(final String chars) {
    Observable.zip(
        Observable.create(new Observable.OnSubscribe<Path>() {
            // all the drawing stuff here
            ...
        }),
        Observable.timer(0, 50, TimeUnit.MILLISECONDS),
        new Func2<Path, Long, Path>() {
            @Override
            public Path call(Path path, Long aLong) {
                return path;
            }
        }
    )
    .subscribeOn(Schedulers.newThread())
    .observeOn(AndroidSchedulers.mainThread())
    ...
}
Run Code Online (Sandbox Code Playgroud)