Rx Java Android:如何将此回调块转换为Observer

时间:2017-04-01 03:44:04

标签: callback rx-java rx-android

我正在尝试通过亚马逊的S3 Android SDK上传文件。我已经使用了RX Java,但我不确定如何将此方法转换为返回Observable的方法,因为我想将此方法的结果链接到另一个Observable调用。我认为这让我感到困惑,因为它不会立即返回,并且在OnError或OnState更改之前无法返回。如何以RX方式处理这些情况?

public void uploadFile(TransferObserver transferObserver){

    transferObserver.setTransferListener(new TransferListener() {
        @Override
        public void onStateChanged(int id, TransferState state) {

        }

        @Override
        public void onProgressChanged(int id, long bytesCurrent, long bytesTotal) {

        }

        @Override
        public void onError(int id, Exception ex) {

        }
  });

}

如果有人可以用RX Java 2和lambdas回答那会很棒,因为我只是在这个问题上做得不够

2 个答案:

答案 0 :(得分:1)

这通常是在异步/回调工作与被动之间建立桥梁的正确方法,但现在不鼓励使用Observable.create(),因为它需要先进的知识才能使其正确。
您应该使用更新的创建方法Observable.fromEmitter(),它看起来完全相同:

    return Observable.fromEmitter(new Action1<Emitter<Integer>>() {
        @Override
        public void call(Emitter<Integer> emitter) {

            transObs.setTransferListener(new TransferListener() {
                @Override
                public void onStateChanged(int id, TransferState state) {
                    if (state == TransferState.COMPLETED)
                        emitter.onCompleted();
                }

                @Override
                public void onProgressChanged(int id, long bytesCurrent, long bytesTotal) {

                }

                @Override
                public void onError(int id, Exception ex) {
                    emitter.onError(ex);
                }
            });
            emitter.setCancellation(new Cancellable() {
                @Override
                public void cancel() throws Exception {
                    // Deal with unsubscription:
                    // 1. unregister the listener to avoid memory leak
                    // 2. cancel the upload 
                }
            });
        }
    }, Emitter.BackpressureMode.DROP);

这里添加的是:处理unsusbcription:取消上传,取消注册以避免内存泄漏,并指定背压策略。
你可以阅读更多here

补充说明:

  • 如果您对进度感兴趣,可以通过onProgressChanged()调用onNext()并将Observable转换为Observable<Integer>
  • 如果没有,您可能需要考虑使用Completable哪个是Observable而没有onNext()排放但只有onCompleted()如果您对进度指示不感兴趣,这可能适合您的情况。

答案 1 :(得分:0)

@Yosriz我无法让你的代码编译,但是你确实对我有所帮助,所以基于你的答案我现在拥有的是:

return Observable.fromEmitter(new Action1<AsyncEmitter<Integer>>() {
            @Override
            public void call(AsyncEmitter<Integer> emitter) {

                transObs.setTransferListener(new TransferListener() {
                    @Override
                    public void onStateChanged(int id, TransferState state) {
                        if (state == TransferState.COMPLETED)
                            emitter.onCompleted();
                    }

                    @Override
                    public void onProgressChanged(int id, long bytesCurrent, long bytesTotal) {

                    }

                    @Override
                    public void onError(int id, Exception ex) {
                        emitter.onError(ex);
                    }
                });

                emitter.setCancellation(new AsyncEmitter.Cancellable() {
                    @Override
                    public void cancel() throws Exception {

                        transObs.cleanTransferListener();
                    }
                });
            }
        }, AsyncEmitter.BackpressureMode.DROP);