我解析中可观察到的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())
...
}
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())
...
}