Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/229.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
RXJava改造等待UI等待从API获取数据_Java_Android_Api_Retrofit - Fatal编程技术网

RXJava改造等待UI等待从API获取数据

RXJava改造等待UI等待从API获取数据,java,android,api,retrofit,Java,Android,Api,Retrofit,我正在学习android开发,我正在使用RXJava进行改造,以与API交互。因此,我成功地从API中获取了数据。现在的问题是,在获取数据之前,程序会继续运行。如何等待从API下载数据,然后运行某些函数 我有一个改装客户端,如图所示 public class RetrofitClient { private static Retrofit retrofit = null; private RetrofitClient() { } public static

我正在学习android开发,我正在使用RXJava进行改造,以与API交互。因此,我成功地从API中获取了数据。现在的问题是,在获取数据之前,程序会继续运行。如何等待从API下载数据,然后运行某些函数

我有一个改装客户端,如图所示

public class RetrofitClient {

    private static Retrofit retrofit = null;

    private RetrofitClient() {

    }

    public static Retrofit getClient(String baseUrl) {
        if (retrofit == null) {
            retrofit = new Retrofit.Builder()
                    .baseUrl(baseUrl)
                    .addConverterFactory(SimpleXmlConverterFactory.create())
                    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                    .build();
        }
        return retrofit;
    }
}
我这样做API调用

public void getData(MyFragment Fragment) {

        mAPIService.getData()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<Data>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.i("ERROR IN GET DATA", e.toString());
                    }
                    @Override
                    public void onNext(Data response) {
                        Log.i("MY DATA", response.toString());
                        fragment.downloadData(response);
                    }

                });
}
这是我从APICaller运行的downloadData函数

  public void downloadData(Data data) {
        this.data = data;
    }

您需要等待RxJava流发出一个值(错误或响应)

首先,对于这一点,如果你期望一个“单一”的发射,成功或失败,我会使用一个
single
。目前,它看起来像是您的
mAPIService.getData()
方法正在返回一个
可观察的
。这些都是为将要发出多个值的流而准备的,在你们的原因中,我假设这不是将要发生的事情。您只有一个要发出的项,因此我将考虑返回一个
单条
。不是你问题的一部分,仅供参考

我喜欢做的是告诉我的用户界面,无论我做什么都是“加载”,通常在
doOnSubscribe
中。然后UI知道显示加载图标或不允许用户交互或其他操作。类似这样的事情(注意,注意它是如何在
observeOn(AndroidSchedulers.mainThread)
之后进行的。任何时候你与UI元素交互时,都要在主线程上进行。我想这可以做到):

mAPIService.getData()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnSubscribe(新消费者(){
@凌驾
public void accept(一次性)引发异常{
片段加载();
}
})
然后,当订阅中返回
onError
onSuccess
时,您会告诉UI它准备好继续了。然后,您可以获得有效的响应,也可以向用户显示错误

编辑:反应式编程

在您的评论之后,您似乎不理解反应式编程。它有一个陡峭的学习曲线,我至今仍在挣扎

您的
APICaller
类,无论它是什么,都应该返回
可观察的
本身。您不应该将
片段传递给此文件,并在其中处理它,因为您正在向内存泄漏和有点代码味道敞开大门。更好的选择是只返回由
mAPIService.getData()
返回的
Observable
。就这样。目前,您正在使用Schedulers.io()
Observable
推送到另一个线程,它对您的主线程说,请继续,不要等我。然后,当使用代码
.observeOn(AndroidSchedulers.mainThread())发出响应时,您将返回到此线程。

然后在片段中处理值或错误的发射。然后,片段代码变为:

button.setOnClickListener(v->{
APICaller.getData()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(新订户(){
@凌驾
未完成的公共无效(){
}
@凌驾
公共无效申报人(可丢弃的e){
i(“获取数据时出错”,例如toString());
}
@凌驾
public void onNext(数据响应){
Log.i(“我的数据”,response.toString());
this.data=响应
Log.i(“TEST:+data.toString());
}
});
});

我建议您观看一些教程,进行一些阅读,我还想让您回到我的观点,即开始时的
Single
s

您需要等待RxJava流发出一个值(错误或响应)

首先,对于这一点,如果你期望一个“单一”的发射,成功或失败,我会使用一个
single
。目前,它看起来像是您的
mAPIService.getData()
方法正在返回一个
可观察的
。这些都是为将要发出多个值的流而准备的,在你们的原因中,我假设这不是将要发生的事情。您只有一个要发出的项,因此我将考虑返回一个
单条
。不是你问题的一部分,仅供参考

我喜欢做的是告诉我的用户界面,无论我做什么都是“加载”,通常在
doOnSubscribe
中。然后UI知道显示加载图标或不允许用户交互或其他操作。类似这样的事情(注意,注意它是如何在
observeOn(AndroidSchedulers.mainThread)
之后进行的。任何时候你与UI元素交互时,都要在主线程上进行。我想这可以做到):

mAPIService.getData()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnSubscribe(新消费者(){
@凌驾
public void accept(一次性)引发异常{
片段加载();
}
})
然后,当订阅中返回
onError
onSuccess
时,您会告诉UI它准备好继续了。然后,您可以获得有效的响应,也可以向用户显示错误

编辑:反应式编程

在您的评论之后,您似乎不理解反应式编程。它有点
  public void downloadData(Data data) {
        this.data = data;
    }