如何在rxJava中返回值

时间:2016-10-21 09:15:55

标签: android rx-java

我是rxJava的新手,它让我头晕目眩。基本上我是通过改造来从youtube api中提取数据,这会改回Observable,并且使用youtubeDataMapper,我将它转换为包含String videoID的Youtube Pojo对象。所以我的问题是,如何让这个方法返回该字符串而不是Completable?

这是我的方法:

@Override
  public Completable downloadVideoUrl(String query) {

    addSubscription(youtubeApi.getYoutubeId(query, Constants.youtubeApi)
                              .map(youtubeDataMapper::map)
                              .subscribeOn(subscribeScheduler)
                              .observeOn(observeScheduler)
                              .subscribe());
    return Completable.complete();
}

2 个答案:

答案 0 :(得分:5)

您有两种选择:

  1. downloadVideoUrl返回Observable代替Completable

    首选方式:

    @Override
    public Completable downloadVideoUrl(String query) {
        return youtubeApi.getYoutubeId(query, Constants.youtubeApi)
                .map(youtubeDataMapper::map)
                .subscribeOn(subscribeScheduler)
                .observeOn(observeScheduler);
    }
    

    请注意此处缺少subscribe运算符。

    然后,无论您想要获取videoId:

    downloadVideoUrl(query)
        .subscribe(new Subscriber<String>() {
                    @Override
                    public void onCompleted() {
    
                    }
    
                    @Override
                    public void onError(Throwable e) {
    
                    }
    
                    @Override
                    public void onNext(String videoId) {
                        // do whatever you want with videoId
                    }
                });
    
  2. 使用toBlocking().first()

    Thread完成

    之前阻止当前Observable,这不是优先考虑的
    @Override
    public String downloadVideoUrl(String query) {
        return youtubeApi.getYoutubeId(query, Constants.youtubeApi)
                .map(youtubeDataMapper::map)
                .subscribeOn(subscribeScheduler)
                .observeOn(observeScheduler)
                .toBlocking().first();
    }
    

答案 1 :(得分:0)

首先,最好让Retrofit返回Single而不是Observable,因为你期望单个服务器响应(而不是一系列响应)。

其次,Completable.complete()是Completable的工厂方法,它根本不做任何事情。所以你在这里不需要它。

关于String videoID,它取决于您计划使用它做什么。另外,我不知道你的.addSubscription()正在做什么。

我建议做类似以下的事情:


class YourClass {

    private final CompositeSubscription compositeSubscription = new CompositeSubscription();
    // you must call compositeSubscription.clear() either in class .finalize() or on some UI lifecycle event

    void yourMethod() {
        final Single videoID = youtubeApi.getYoutubeId(query, Constants.youtubeApi)
                .map(youtubeDataMapper::map)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
        final Subscription subscription = videoID.subscribe(new SingleSubscriber() {                    
                    @Override
                    public void onSuccess(String value) {
                        // TODO: do whatever with the value
                    }
                    @Override
                    public void onError(Throwable error) {                         
                        // TODO: log and/or display error
                    }
                });
       compositeSubscription.add(subscription);
    }
}