在Android上使用RxJava以固定的时间间隔发出用于在UI中绘制的对象

在Android上使用RxJava以固定的时间间隔发出用于在UI中绘制的对象,android,rx-java,Android,Rx Java,我正在以可观察的方式解析SVG文件。解析XML时,点作为“路径”对象发出。解析在单独的线程中进行,我想逐点绘制SVG文件。换句话说,我希望一个接一个地向UI发射点,例如每50毫秒发射一个点 private void drawPath(final String chars) { Observable.create(new Observable.OnSubscribe<Path>() { @Override public void call(Subscribe

我正在以可观察的方式解析SVG文件。解析XML时,点作为“路径”对象发出。解析在单独的线程中进行,我想逐点绘制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
                }

            });

}
private void drawPath(最终字符串字符){
创建(新的Observable.OnSubscribe(){

@覆盖公共无效呼叫(订阅者您需要使用带有
.timer()
.zip()
运算符。来自原始RxJava wiki:

  • 通过指定函数将可观测值组合在一起并发出项 基于此函数的结果

  • 创建一个在给定延迟后发射单个项目的可观察对象

因此,如果使用
zip()
将原始的
Observer
timer()
组合,则可以每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())
    ...
}
private void drawPath(最终字符串字符){
可观察的.zip(
创建(新的Observable.OnSubscribe(){
//这里所有的绘画材料
...
}),
可观察计时器(0,50,时间单位毫秒),
新功能2(){
@凌驾
公共路径调用(路径,长路径){
返回路径;
}
}
)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
...
}

您需要将
.zip()
运算符与
.timer()
一起使用。原始RxJava wiki:

  • 通过指定函数将可观测值组合在一起并发出项 基于此函数的结果

  • 创建一个在给定延迟后发射单个项目的可观察对象

因此,如果使用
zip()
将原始的
Observer
timer()
组合,则可以每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())
    ...
}
private void drawPath(最终字符串字符){
可观察的.zip(
创建(新的Observable.OnSubscribe(){
//这里所有的绘画材料
...
}),
可观察计时器(0,50,时间单位毫秒),
新功能2(){
@凌驾
公共路径调用(路径,长路径){
返回路径;
}
}
)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
...
}

public Path call(Path Path,Long-aLong)似乎有语法错误,上下文帮助告诉我需要span作为返回参数:public-span-call(SVGPath Path,Long-aLong)。当我将drawPath()放在这个调用中时,它仍然会立即引发,因此我假设必须在observeOn()之后附加.subscribe()我不知道我之前的评论到哪里去了,但我们又来了:我在开始的时候在答案中输入的代码有一个拼写错误(span是我在本地输入的代码片段的一部分,必须被视为拼写错误)。尽管如此,答案中的代码已经被修复,并提供了更多的参考。public path call(Path Path,Long-aLong)似乎有一个语法错误,上下文帮助告诉我需要span作为返回参数:public-span-call(SVGPath Path,Long-aLong)。当我将drawPath()放在这个调用中时,它仍然会立即引发,所以我假设我必须在observeOn()之后附加.subscribe()我不知道我之前的评论到哪里去了,但我们又来了:我在开始的时候在答案中输入的代码有一个拼写错误(span是我在本地输入的代码片段的一部分,必须被视为一个拼写错误)。尽管如此,答案中的代码已经修复,并提供了更多的参考。