我知道如何保存状态并恢复它们,但是当我必须使用Web服务并更新UI时,我感到很困惑。有时我使用的是AsyncTask,但后来我指出了我放松活动/片段上下文的地方,例如当我旋转设备时。所以就这样,我在想其他应用程序是如何处理这种情况的。
如果我使用IntentService
并从那里调用我的Web服务,那么我开始认为对于每个Web服务,我必须以不同的方式使IntentService,并更新我必须制作的每个活动和片段的UI BroadcastReceiver用于每个活动和片段。
那么从活动和片段调用Web服务的好习惯是什么?
如何在服务返回到达时更新UI(或根据第一个服务结果调用下一个服务)?
答案 0 :(得分:4)
如果您希望通过配置更改(您这样做)立即获得数据,那么您可能希望使用加载程序。
它为开发人员提供了一种为活动或片段异步加载数据的机制。由于加载器专门用于解决异步加载问题,因此无需花费太多时间设计异步任务来有效处理所有不同的场景。
关于装载机的好文章https://medium.com/google-developers/making-loading-data-on-android-lifecycle-aware-897e12760832
答案 1 :(得分:1)
尝试使用retrofit。它是Android应用程序的一个很棒的网络库,它易于使用。
整个网络调用+ JSON / XML解析完全由它处理(在Gson的帮助下进行JSON解析)。文档很棒,社区也很庞大。
查看此sample。
答案 2 :(得分:1)
我注意到你做了一个评论:
...我的网络服务是肥皂,我无法改变它们
我正在调用我的Web服务(也就是SOAP)的方式是通过Intent
。我这样做是通过传递我使用putExtra
提交给Web服务的数据,然后在我的WebService上接收它,就像你现在可能做的那样。然后,我从该Web调用中获取结果并在AsyncTask
内处理,异步任务将使用EventBus根据需要发布到结果,这些结果通过ThreadMode.Main在我的MainThread上接收。
因此,我强烈建议使用EventBus中名为Greenrobot的库。
您可以极大地简化活动和片段之间的通信,您可以使用代码中任何位置提供的默认EventBus实例立即开始使用。例如,您可以执行以下操作。
EventBus.getDefault().post(new ModelForOtherActivityToSee(data));
在模型中,您可以包含您想要的任何内容,并在收到时做出相应的反应。
最好的部分是,收到后,EventBus会处理如何通过运行ASYNC,MAIN,BACKGROUND来执行数据
ASYNC - 在单独的线程中调用事件处理程序方法。这始终独立于发布线程和主线程。发布事件永远不会等待使用此模式的事件处理程序方法。如果执行可能需要一些时间,例如事件处理程序方法应使用此模式。用于网络访问。避免同时触发大量长时间运行的异步处理程序方法来限制并发线程数。 EventBus使用线程池从已完成的异步事件处理程序通知中有效地重用线程。
背景 - 将在后台线程中调用订阅者。如果发布线程不是主线程,则将在发布线程中直接调用事件处理程序方法。如果发布线程是主线程,则EventBus使用单个后台线程,该线程将按顺序传递其所有事件。使用此模式的事件处理程序应尝试快速返回以避免阻塞后台线程。
MAIN -Subscribers将在Android的主线程中调用(有时称为UI线程)。如果发布线程是主线程,则将直接调用事件处理程序方法(与ThreadMode.POSTING所描述的同步)。使用此模式的事件处理程序必须快速返回以避免阻塞主线程。
接收从EventBus
广播的事件的示例:
//ThreadMode can be ASYNC, MAIN, BACKGROUND
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(ModelForOtherActivityToSee eventModel) {
/* Do something with eventModel received, this runs on UI thread */
};
有关如何使用EventBus的完整示例:
1 - 打开应用的build.gradle并设置EventBus的依赖关系:
dependencies { compile 'org.greenrobot:eventbus:3.0.0'}
2 - 创建用于发布EventBus的第一个模型,我将使用一个非常简单的模型示例:
package com.myapp.models.eventbusmodels;
public final class EventBusMyModel {
private final String dataRaw
public EventBusMyModel(final String rawData) {
this.dataRaw = rawData;
}
public String getRawData() {
return this.dataRaw;
}
}
3 - 现在剩下的就是从任何地方推出广播。
EventBus.post(new EventBusModel("My Data here"));
4 - 要启用活动/片段以从EventBus接收事件,您必须附加和分离,这就是我的意思。来自onResume()
和onStop()
覆盖的活动内部:
public class SomeActivity {
@Override
protected void onResume() {
if(!EventBus.getDefault().isRegistered(this))
EventBus.getDefault().register(this);
}
@Override
protected void onStop() {
if(EventBus.getDefault().isRegistered(this))
EventBus.getDefault().unregister(this);
super.onStop();
}
}
5 - 最后要做的是接收该广播,您可以在任何片段,活动或所有片段/活动中接收它。以下是SomeActivity
内部的示例:
@Subscribe(threadMode = ThreadMode.MAIN)
public void eventThisNameDoesNotMatter(final EventBusMyModel resultModel) {
String receivedData = resultModel.getRawData();
//Do whatever with receivedData. Since we are on ThreadMode.MAIN, this is on the UI thread.
}