RxJava sample() 是 CPU 密集型

RxJava sample() is CPU intensive

我正在尝试使用 RxJava 实现下载进度条(在 Android 上)。我希望能够以 0.1% 的分辨率报告(下载)进度。但是,如果连接速度很快,文件可能会很快下载并产生很多事件。

因此我假设我必须使用 .sample() 来限制事件的数量。我的实现如下所示:

        mRxSubscription = downloadProgressChangeObservable
                .ofType(DownloadProgress.class)
                .sample(16, TimeUnit.MILLISECONDS) // This is problematic
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<DownloadProgress>() {
                    @Override
                    public void call(DownloadProgress downloadProgress) {
                        Log.v(TAG, "Recieved downloadProgress event. Progress: " + downloadProgress.getProgress());
                        setProgressPercent(downloadProgress);
                    }
                }, new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        Log.d(TAG, "error: " + throwable.toString());
                    }
                });

如果我只有订阅(没有 .sample() )一切正常,除非下载管理器发出事件的速度太快。然而,添加 .sample() 我的 CPU 负载始终增加到 ~30% - 即使没有事件被发出。

我不确定我是否理解这一点。 call(DownloadProgress) 和 call(Throwable) 都没有被调用,但感觉订阅在不断拉取新事件。

来自 sample 文档,

The Sample operator periodically looks at an Observable and emits whichever item it has most recently emitted since the previous sampling.

"Looks at" 表示它在每个周期都在工作,这说明了您的 CPU 使用情况。每 16 毫秒,它就会发射一次并查看是否需要发射物品。根据您的 UI 约束条件,您可能应该将其调回 100-500 毫秒。