RXJava改造等待UI等待从API获取数据
我正在学习android开发,我正在使用RXJava进行改造,以与API交互。因此,我成功地从API中获取了数据。现在的问题是,在获取数据之前,程序会继续运行。如何等待从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
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;
}