【问题标题】:Return Observable in callback rxjava在回调 rxjava 中返回 Observable
【发布时间】:2016-06-30 09:31:51
【问题描述】:

我正在搞乱一些 google 感知 api,现在我对 RxJava 的理解限制了我。

我最终想要达到的目标: 我想从 Api 获取天气和位置,并将它们合并到一个对象中,我可以将其传递给我的视图进行更新。

但是,我不确定如何从此处的 api 回调中实现 Observable 的返回,因为它具有 void 返回类型,以及如何实现从 api.getWeather 和 api.getLocation 合并天气和位置对象

public void requestUserCurrentInfo() {
    Subscription userInfo = getWeatherLocation().subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread()).subscribe(userinfo ->
                    Log.d(TAG,userinfo.something()));
}

public Observable<UserInfo> getWeatherLocation () {
    try {
        Awareness.SnapshotApi.getWeather(client)
                .setResultCallback(weather -> {
                    if (!weather.getStatus().isSuccess()) {
                        Log.d(TAG, "Could not get weather");
                        return;
                    }
                    //How do I do here?
                    return weather.getWeather();
                });


        Awareness.SnapshotApi.getLocation(mGoogleApiClient)
            .setResultCallback(retrievedLocation -> {
                if(!retrievedLocation.getStatus().isSuccess()) return;
                Log.d("FRAG", retrievedLocation.getLocation().getLatitude() + "");
            });


    } catch (SecurityException exception) {
        throw new SecurityException("No permission " + exception);

    }

}

对于我项目中的其他事情,我通过遵循存储库模式的 REST api 得到一些东西,然后我可以像这样得到它,因为每一步都返回一个 Observable

getWeatherSubscription = getWeatherUsecase.execute().subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread()).subscribe(
                    smhiResponseModel -> {Log.d(TAG,"Retrieved weather"); locationView.hideLoading();},
                    err -> {Log.d(TAG,"Error fetching weather"); locationView.hideLoading();}
            );

【问题讨论】:

    标签: java android rx-java reactive-programming


    【解决方案1】:

    您不会从回调中返回 observable,而是将回调包装到 observable 中以使它们可组合(未经测试):

        Observable<WeatherResult> weatherObservable = Observable.create(subscriber -> {
            Awareness.SnapshotApi.getWeather(client)
                    .setResultCallback(weather -> {
                        if (!weather.getStatus().isSuccess()) {
                            subscriber.onError(new Exception("Could not get weather."));
                            Log.d(TAG, "Could not get weather");
                        } else {
                            //How do I do here?
    
                            subscriber.onNext(weather);
                            subscriber.onCompleted();
                        }
                    });
        });
    
        Observable<LocationResult> locationObservable = Observable.create(subscriber -> {
            Awareness.SnapshotApi.getLocation(mGoogleApiClient)
                    .setResultCallback(retrievedLocation -> {
                        if(!retrievedLocation.getStatus().isSuccess()) {
                            subscriber.onError(new Exception("Could not get location."));
                        } else {
                            Log.d("FRAG", retrievedLocation.getLocation().getLatitude() + "");
                            subscriber.onNext(retrievedLocation);
                            subscriber.onCompleted();
                        }
                    });
        });
    

    现在通过.combineLatest().zip() 组合它们:

        Observable<CombinedResult> combinedResults = Observable.zip(weatherObservable, locationObservable,
                (weather, location) -> {
                    /* somehow combine weather and location then return as type "CombinedResult" */
                });
    

    别忘了订阅,否则它们都不会被执行:

        combinedResults.subscribe(combinedResult -> {/*do something with that stuff...*/});
    

    【讨论】:

    • 非常感谢,就像一个魅力,当你这样写时非常有意义
    • Z 在这种情况下我将如何管理退订?
    • 你不需要。终止后(即 onError 或 onCompleted 在订阅服务器上执行)取消订阅无论如何都不会做任何事情,因为您已经收到了所有元素(实际上它只是一个)或引发了错误。无论哪种方式,observable 都终止了......
    【解决方案2】:
    Observable.combineLatest(getWeather (), getLocation(), new Func2<List<Object_A>, List<Object_B>, Object>() {
                @Override
                public Object call(Object o, Object o2) {
                    combine both results and return the combine result to observer
                }
            })
    

    getweather() 和 getlocation() 返回 observables

    【讨论】:

    • 不确定你的意思,来自 api 的实际方法看起来像 Awareness.SnapshotApi.getWeather(mGoogleApiClient) .setResultCallback(new ResultCallback() { @Override public void onResult(@NonNull WeatherResult weatherResult) { if (!weatherResult.getStatus().isSuccess()) { return; } 天气天气 = weatherResult.getWeather(); } });
    • 我的意思是 getweather() 和 getlocation() 应该分别返回一个 observable,然后使用 combinelatest 将这两个 observable 合并为一个 observable
    • 是的,到目前为止我和你在一起,但是当我尝试将天气或位置作为可观察返回时它会抱怨。我该怎么做,使用 Observable.just(weather) 或 Observable.create...?
    • 我的问题仍然在于我无法返回。如果我让 Observable.create(new Observable.onSubscribe ... 编译器仍然会说;不兼容的类型:预期 void 但 lambda 主体既不是语句也不是 void 兼容块
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多