【问题标题】:RxJava chain calls lagsRxJava 链调用滞后
【发布时间】:2017-03-01 20:58:08
【问题描述】:
mDisposable = mAdapter.getPublisher()
.subscribeOn(Schedulers.io())
.map(new Function<CreateVideoRx, CreateVideoRx>() {

    @Override
    public CreateVideoRx apply(CreateVideoRx createVideoRx) throws Exception {
        Bitmap bitmap = mMediaMetadataRetriever.getFrameAtTime(createVideoRx.time * 1000000, MediaMetadataRetriever.OPTION_CLOSEST);
        bitmap = ThumbnailUtils.extractThumbnail(bitmap, 50, 90);
        createVideoRx.mBitmap = bitmap;
        return createVideoRx;
    }
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<CreateVideoRx>() {
    @Override
    public void accept(CreateVideoRx createVideoRx) throws Exception {
        createVideoRx.mImageView.setImageBitmap(createVideoRx.mBitmap);
    }
});

这个 RxJava 链有效。但是我仍然做错了什么,因为它滞后并且感觉它不像在后台线程上工作。这种情况下IO线程会做什么,MainThread会做什么?

我以前用 AsyncTask 做过这个。它工作得很好,但现在我想跳过它并改用 RxJava。我得到的结果是工作,但它滞后了很多。

编辑:添加了更多信息

  private final PublishSubject<CreateVideoRx> mPublisher = PublishSubject.create();

上面的对象在mAdapter.getPublisher()中被调用,函数本身看起来像

  public PublishSubject<CreateVideoRx> getPublisher() {
    return mPublisher;
  }

我想做的是在后台线程上提取缩略图。然后当它完成后,我希望它被推送到单个 ImageView。

【问题讨论】:

  • 可能是由于createVideoRx 上的竞争条件;看起来您在多个线程之间共享同一个实例,而不是发送不可变数据,例如缩略图本身到 GUI 线程。
  • 您希望在 io 线程上完成哪些代码块?
  • 我希望我可以在 io 线程中执行第一个块。但是今天早上注意到两者都在 main 中执行。
  • 什么是mAdapter.getPublisher()
  • 添加了更多信息

标签: android rx-java rx-android


【解决方案1】:

“在 RxJava 中,您可以使用 subscribeOn() 告诉您的 Observable 代码在哪个线程上运行,以及您的订阅者应该使用 observeOn() 在哪个线程上运行”。然而,操作员订阅源 observable 的事实使这变得复杂。

我保持直截了当的方式是记住subscribeOn() 会影响函数上游的所有内容,而observeOn 会影响函数下游的所有内容。您在原始问题中应该做的是

mDisposable = mAdapter.getPublisher()    
.map(new Function<CreateVideoRx, CreateVideoRx>() {

    @Override
    public CreateVideoRx apply(CreateVideoRx createVideoRx) throws Exception {
        Bitmap bitmap = mMediaMetadataRetriever.getFrameAtTime(createVideoRx.time * 1000000, MediaMetadataRetriever.OPTION_CLOSEST);
        bitmap = ThumbnailUtils.extractThumbnail(bitmap, 50, 90);
        createVideoRx.mBitmap = bitmap;
        return createVideoRx;
    }
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<CreateVideoRx>() {
    @Override
    public void accept(CreateVideoRx createVideoRx) throws Exception {
        createVideoRx.mImageView.setImageBitmap(createVideoRx.mBitmap);
    }
});

【讨论】:

    【解决方案2】:
            mDisposable = mAdapter.getPublisher()
                .observeOn(Schedulers.io())
                .map(new Function<CreateVideoRx, CreateVideoRx>() {
                    @Override
                    public CreateVideoRx apply(CreateVideoRx createVideoRx) throws Exception {
                        Bitmap bitmap = mMediaMetadataRetriever.getFrameAtTime(createVideoRx.time * 1000000, MediaMetadataRetriever.OPTION_CLOSEST);
                        bitmap = ThumbnailUtils.extractThumbnail(bitmap, 50, 90);
                        createVideoRx.mBitmap = bitmap;
                        return createVideoRx;
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<CreateVideoRx>() {
                    @Override
                    public void accept(CreateVideoRx createVideoRx) throws Exception {
                        createVideoRx.mImageView.setImageBitmap(createVideoRx.mBitmap);
                    }
                });
    

    这解决了我的问题。但我仍然不完全理解 SubscribeOn 和 ObserveOn 之间的区别

    【讨论】:

      猜你喜欢
      • 2020-01-02
      • 1970-01-01
      • 1970-01-01
      • 2017-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-01
      • 1970-01-01
      相关资源
      最近更新 更多