发射的物体使用RxJava Android上以规则的间隔在UI绘制间隔、物体、上以、规则

2023-09-07 21:57:50 作者:sI淰ɡцδー秒…

我解析中可观察到的SVG文件。作为XML解析点发射的路径对象。解析发生在一个单独的线程,我想绘制由点SVG文件点。换句话说,我想以发射点到UI逐一,例如,一个每50毫秒。

 私人无效drawPath(最后弦乐字符){

    Observable.create(新Observable.OnSubscribe<路径>(){

        @覆盖公共无效呼叫(订户LT ;?超级路径>用户){
            尝试 {

                而([略]){

                    //省略:很多加工
                    //从SVG文件的XML路径被解析成一个机器人路径中的画布上绘制
                    //这种情况逐点

                    subscriber.onNext(路径); //发射路径逐点作为XML处理
                }
            }
                subscriber.onCompleted();
            }赶上(例外五){
                subscriber.onError(E);
            }
        }

    }),缓冲区(50,TimeUnit.MILLISECONDS,1)//延迟每个点,使用户界面可以处理它,而不是淹没
            .subscribeOn(Schedulers.newThread())。observeOn(AndroidSchedulers.mainThread())
            .subscribe(新措施1<列表<路径>>(){

                @覆盖公共无效电话(名单<路径>路径){
                    的System.out.println(**** SVG分析器:drawPath UI线程上);

                    如果(paths.size()大于0){drawPath(paths.get(0),漆); }

                }

            },新措施1<可抛出>(){

                @覆盖公共无效通话(可抛出抛出){
                    throwable.printStackTrace(); //忽略默默地
                }

            });

}
 

当我使用.buffer()如图所示,每条路径都尽快产生排放。该.buffer()似乎并没有在这里做任何事情。

我试图.throttle(),但随后分被省略了。

我怎样才能使这项工作?

BTW:有没有回来pressure此问题,因为它是分析的SVG文件是有限的。我只想解析它在一个单独的线程,缓存的结果,放出他们慢。

解决方案

您需要使用的.zip()操作符与 .timer ()。从最初的RxJava维基:

拉链() :

  

通过指定的功能结合在一起观测量和发射项目   基于该函数的结果

定时器() :

  

创建一个可观察到的,给定的延迟之后发出一个单一的项目

所以,如果你使用的zip()要结合你原来的观察定时器(),可以延迟每个路径的输出每隔50毫秒:

 私人无效drawPath(最后弦乐字符){
    Observable.zip(
        Observable.create(新Observable.OnSubscribe<路径>(){
            //所有绘制这里的东西
            ...
        }),
        Observable.timer(0,50,TimeUnit.MILLISECONDS),
        新FUNC2<路径,龙,路径和GT;(){
            @覆盖
            公共路径调用(路径路径,沿着龙){
                返回路径;
            }
        }
    )
    .subscribeOn(Schedulers.newThread())
    .observeOn(AndroidSchedulers.mainThread())
    ...
}
 
Android 之路 RxJava2 Retrofit实现简单登陆

I am parsing SVG files in an Observable. Points are emitted as "Path" object as the XML is parsed. Parsing happens in a separate thread and I want to draw the SVG file point by point. In other words, I want to emit the points to the UI one by one, for example one every 50 msec.

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
                }

            });

}

When I use .buffer() as shown, each Path is emitted as soon as it is produced. The .buffer() seems not to do anything here.

I have tried to .throttle(), but then points are omitted.

How can I make this work?

BTW: There is no backpressure issue here as the SVG file which is parsed is finite. I only want to parse it in a separate thread, buffer the results and emit them slowly.

解决方案

You need to use the .zip() operator with a .timer(). From original RxJava wiki:

zip():

combine Observables together via a specified function and emit items based on the results of this function

timer():

create an Observable that emits a single item after a given delay

So, if you use zip() to combine your original Observer with timer(), you can delay the output of each Path every 50 msecs:

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())
    ...
}