Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/212.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 使用RxJava和改型2在登录成功后执行一些操作_Android_Rx Java_Retrofit2_Flatmap - Fatal编程技术网

Android 使用RxJava和改型2在登录成功后执行一些操作

Android 使用RxJava和改型2在登录成功后执行一些操作,android,rx-java,retrofit2,flatmap,Android,Rx Java,Retrofit2,Flatmap,我实现了网络调用以验证登录,这很正常。我只是在登录成功后再次调用以获取用户数据时遇到了一些问题 以下是API调用: RestApi restApi = ServiceRest.createRetrofitService(RestApi.class, UrlServer.URL_SERVER); Observable<Response<User>> responseObservable = restApi.getUser(user); responseObservable.

我实现了网络调用以验证登录,这很正常。我只是在登录成功后再次调用以获取用户数据时遇到了一些问题

以下是API调用:

RestApi restApi = ServiceRest.createRetrofitService(RestApi.class, UrlServer.URL_SERVER);
Observable<Response<User>> responseObservable = restApi.getUser(user);
responseObservable.subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .unsubscribeOn(Schedulers.io())
        .subscribe(new Subscriber<Response<User>>() {
            @Override
            public void onCompleted() {
                Log.i("LoginActivity", "[onCompleted]");
                progressDialog.dismiss();
            }

            @Override
            public void onError(Throwable e) {
                progressDialog.dismiss();
                Toast.makeText(LoginActivity.this, "Error: " + e.getMessage(), Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onNext(Response<User> userResponse) {
                //Do stuff to go to another Activity
            }
        });
-------编辑1-------

我实现了@Tassos的建议,如下所示:

responseUser
         .subscribeOn(Schedulers.io())
         .observeOn(AndroidSchedulers.mainThread())
         .map(new Func1<Response<User>, Observable<Response<Object>>>() {
                 @Override
                 public Observable<Response<Object>> call(Response<User> userResponse) {
                     Log.d("USER", userResponse.body().getName());
                     return restApi.getData(userResponse.body().getToken());
                 }
            })
            .doOnError(new Action1<Throwable>() {
                @Override
                public void call(Throwable throwable) {
                    Toast.makeText(LoginActivity.this, "Error[doOnError]: " + throwable.toString(), Toast.LENGTH_SHORT).show();
                }
            })
            .subscribe(new Subscriber<Object>() {
                @Override
                public void onCompleted() {
                    Log.i("LoginActivity", "[onCompleted]");
                }
                @Override
                public void onError(Throwable e) {
                    Toast.makeText(LoginActivity.this, "Error: " + e.getMessage(), Toast.LENGTH_SHORT).show();
                }
                @Override
                public void onNext(Object result) {
                    Log.d("RESPONSE", result.toString());
                }
            });
在subscribe方法上这样做正确吗?是否需要强制转换onNext的对象结果

//--------------------------------------//

我想在登录成功后,使用通过响应对象用户获得的令牌调用另一个url,并将其发送给另一个api调用getData@HeaderAuthorization字符串标记;作为标头的授权。 我曾尝试使用flatMap和zip,但未能完成此任务。 有什么建议吗?这个概念对我来说是新概念。

那么,您真的需要用户关闭对话框吗?在进行其他调用之前,是否确实需要关闭该对话框

    .unsubscribeOn(Schedulers.io())
    .map(userResponse -> { /* do the other calls */ }
    .subscribe(new Subscriber<?>() {...
那么,您真的需要用户关闭对话框吗?在进行其他调用之前,是否确实需要关闭该对话框

    .unsubscribeOn(Schedulers.io())
    .map(userResponse -> { /* do the other calls */ }
    .subscribe(new Subscriber<?>() {...
.flatMap运算符是执行一个API调用然后执行另一个API调用的完美方法。在这里阅读:它得到了更好的部分

.flatMap允许您将一个可观察对象更改为另一个,即使用前一个的结果进行新的API调用,实现事件链。若您这样做,订阅者将被调用以获取从.flatMap接收到的可观测数据

你只要写:

restApi.getUser(user)
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .flatMap(userResponse -> restApi.getData(userResponse.getToken()))
    .doOnError(e -> Toast.makeText(LoginActivity.this, "Error: " + e.getMessage(), Toast.LENGTH_SHORT).show())
    .doOnTerminate(() -> progressDialog.dismiss())
    .subscribe(response -> proceedWithLogin())
还有,为什么要使用.unsubscribeOnSchedulers.io?当您使用改型观察时,它们通常生成一个事件,然后完成,并且不需要设置取消订阅计划程序

使用.flatMap操作符是执行一个API调用然后执行另一个API调用的完美方法。在这里阅读:它得到了更好的部分

.flatMap允许您将一个可观察对象更改为另一个,即使用前一个的结果进行新的API调用,实现事件链。若您这样做,订阅者将被调用以获取从.flatMap接收到的可观测数据

你只要写:

restApi.getUser(user)
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .flatMap(userResponse -> restApi.getData(userResponse.getToken()))
    .doOnError(e -> Toast.makeText(LoginActivity.this, "Error: " + e.getMessage(), Toast.LENGTH_SHORT).show())
    .doOnTerminate(() -> progressDialog.dismiss())
    .subscribe(response -> proceedWithLogin())

还有,为什么要使用.unsubscribeOnSchedulers.io?当您使用改型观察时,它们通常生成一个事件,然后完成,并且不需要设置取消订阅计划程序

实际上我已经考虑过了,在进行另一次调用之前,我不需要关闭对话框……我需要保留对话框,并将消息从验证用户更改为获取用户数据,在最后一次调用结束时,对话框被关闭。谢谢我在尝试实现您的建议时遇到了一个问题,我将编辑我的问题以显示我对它的实际想法,我不需要在进行另一个调用之前关闭对话框…我需要保留对话框并将消息从验证用户更改为获取用户数据,在最后一次调用结束时,对话框被取消。谢谢我在尝试实现您的建议时遇到了一个问题,我将编辑我的问题以显示我做了什么我尝试了您的解决方案,但返回的是java.net.SocketTimeoutException,然后是rx.exceptions.OnErrorNotImplementedException。我实现了doonerror。java.net.SocketTimeoutException是由getUser还是由getData引起的?您可以尝试do.SubscriberResponse->proceedWithLogin,throwable->Log.dError,throwable.getMessage,因为OnErrorNotImplementedException意味着没有为Observable提供错误处理。我猜,返回错误响应时会调用.doError,但它并不能替代订户的onError调用的实现,我必须强调,如果flatMap背后的计算是异步的,它不会按顺序返回项目。如果您想保持映射的可观察对象的顺序,请使用concatMap。我尝试了您的解决方案,但返回的是java.net.SocketTimeoutException,然后是rx.exceptions.OnErrorNotImplementedException。我实现了doonerror。java.net.SocketTimeoutException是由getUser还是由getData引起的?您可以尝试do.SubscriberResponse->proceedWithLogin,throwable->Log.dError,throwable.getMessage,因为OnErrorNotImplementedException意味着没有为Observable提供错误处理。我猜,返回错误响应时会调用.doError,但它并不能替代订户的onError调用的实现,我必须强调,如果flatMap背后的计算是异步的,它不会按顺序返回项目。如果您想保持映射的可观察对象的顺序,请使用concatMap。