Android rxjava2 Flowable with compositedisposable

时间:2017-04-02 13:40:10

标签: android rx-java observable

我遇到Flowables的问题并将它们添加到compositeDisposables。 我想从Observable切换到Flowable,因为操作可能会发出1000或更多值。我对rxjava2缺乏经验,所以请原谅我,如果这个问题很愚蠢:)

到目前为止,我使用了这样的observable:

 public Observable<String> uploadPictureRx(String path)
    {
        return Observable.create(new ObservableOnSubscribe<String>()
        {
            @Override
            public void subscribe(ObservableEmitter<String> e) throws Exception
            {
                Uri file = Uri.fromFile(new File(path));
                String segment = file.getLastPathSegment();
                UploadTask uploadTask = reference.child("SomeChild").child(segment).putFile(file);


                uploadTask.addOnFailureListener(new OnFailureListener()
                {
                    @Override
                    public void onFailure(@NonNull Exception exception)
                    {
                        e.onError(exception);
                    }
                }).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>()
                {
                    @Override
                    public void onSuccess(UploadTask.TaskSnapshot taskSnapshot)
                    {                           
                        //noinspection VisibleForTests
                        downloadUrl = taskSnapshot.getDownloadUrl();
                        String url = downloadUrl.getPath();
                        e.onNext(url);
                        e.onComplete();
                    }
                }).addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>()
                {
                    @Override
                    public void onProgress(UploadTask.TaskSnapshot taskSnapshot)
                    {
                        //noinspection VisibleForTests
                        long bytes = taskSnapshot.getBytesTransferred();
                        String bytesS = String.valueOf(bytes);
                        e.onNext(bytesS);
                    }
                });
            }
        });
    }

并调用这样的方法:

private void uploadPicToFireBaseStorage(String path)
    {
        compositeDisposable.add(storageService.uploadPictureRx(path)
                .subscribeOn(Schedulers.io())
                .observeOn(mainScheduler)
                .subscribeWith(new DisposableObserver<String>()
                {

                    @Override
                    public void onNext(String s)
                    {
                        String ss = s;
                        System.out.println(ss);
                    }

                    @Override
                    public void onError(Throwable e)
                    {
                        e.printStackTrace();
                    }

                    @Override
                    public void onComplete()
                    {
                        view.displayToast("Picture Upload completed");
                    }
                })
        );
    }

这很好用!但是,当我尝试使用Flowable而不是observable时,它不会编译:

public Flowable<String> uploadPictureRx(String path)
    {
        return Flowable.create(new FlowableOnSubscribe<String>()
        {

            @Override
            public void subscribe(FlowableEmitter<String> e) throws Exception
            {
                Uri file = Uri.fromFile(new File(path));
                String segment = file.getLastPathSegment();
                UploadTask uploadTask = reference.child("somechild").child(segment).putFile(file);    

                uploadTask.addOnFailureListener(new OnFailureListener()
                {
                    @Override
                    public void onFailure(@NonNull Exception exception)
                    {
                        e.onError(exception);
                    }
                }).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>()
                {
                    @Override
                    public void onSuccess(UploadTask.TaskSnapshot taskSnapshot)
                    {                           
                        //noinspection VisibleForTests
                        downloadUrl = taskSnapshot.getDownloadUrl();
                        String url = downloadUrl.getPath();
                        e.onNext(url);
                        e.onComplete();
                    }
                }).addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>()
                {
                    @Override
                    public void onProgress(UploadTask.TaskSnapshot taskSnapshot)
                    {
                        //noinspection VisibleForTests
                        long bytes = taskSnapshot.getBytesTransferred();
                        String bytesS = String.valueOf(bytes);
                        e.onNext(bytesS);
                    }
                });
            }
        }, BackpressureStrategy.BUFFER);

    }

错误是:  推断类型&#39; E&#39;对于类型参数&#39; E&#39;不在其范围内;应该实施&#39; org.reactivestreams.Subscriber

我的猜测是,Flowable没有实现Disposable,这就是为什么它不会编译。我不知道那是不是真的,只是我到目前为止最好的猜测。 或者我是否必须将subscribeWith()更改为subscribe()?我不知道这种改变会带来什么影响。

无论如何建议如何使这个工作并将这个Flowable变成我的compositedisposable非常感谢。

谢谢你们!

编辑:

尝试将DisposableObserver更改为订阅服务器。但是这会导致以下错误: Compiler Error

2 个答案:

答案 0 :(得分:3)

Flowables出于Backpressure的原因使用Subscription而不是Disposable。基本上使用Subscription.request()方法告诉可观察到那个时刻我想要多少项。

更改您的代码:

private void uploadPicToFireBaseStorage(String path)
{
    compositeDisposable.add(storageService.uploadPictureRx(path)
            .subscribeOn(Schedulers.io())
            .observeOn(mainScheduler)
            .subscribeWith(new DisposableObserver<String>()
            {

                @Override
                public void onNext(String s)
                {
                    String ss = s;
                    System.out.println(ss);
                }

                @Override
                public void onError(Throwable e)
                {
                    e.printStackTrace();
                }

                @Override
                public void onComplete()
                {
                    view.displayToast("Picture Upload completed");
                }
            })
    );
}

private void uploadPicToFireBaseStorage(String path)
{
    compositeDisposable.add(storageService.uploadPictureRx(path)
            .subscribeOn(Schedulers.io())
            .observeOn(mainScheduler)
            .subscribeWith(new ResourceSubscriber<String>()
            {
                @Override
                public void onNext(String s)
                {
                    String ss = s;
                    System.out.println(ss);
                }

                @Override
                public void onError(Throwable e)
                {
                    e.printStackTrace();
                }

                @Override
                public void onComplete()
                {
                    view.displayToast("Picture Upload completed");
                }
            })
    );
}

答案 1 :(得分:3)

Flowable根据 pub-sub模式工作,即 publisher - subscriber 模式

然而,

Observable根据观察者模式

工作

pub-sub模式中,有一个中间事件通道保存 publisher发布的数据,然后是event channel 发出数据,subscriber获取onNext(...)中的数据。

然而, 在观察者模式中,observable会直接发送数据或将数据直接投放到observer这可能会造成背压。(因为它会一次性发出整个数据。)

所以使用(Flowable

 .subscribeWith(new ResourceSubscriber<>) // in case of flowable

或者,

 .subscribeWith(new DisposableSubscriber<>) 

而在(observable)的情况下使用

  .subscribeWith(new ResourceObserver<>)