有一种常见的应用程序行为模式,即除非当前操作完成,否则无法进行下一步。一个很好的例子是身份验证:一旦您提供了登录名和密码,并点击“登录”,应用程序会阻塞一段时间,显示一种“等待,我正在工作”的指示器。尽管这个任务非常普遍,但我没有找到一个“典型”的解决方案。
我牢记的主要要点如下:
1. Activity 的生命周期没有任何保证。当用户启动它们时,Activity 保证被启动,但之后它们可以在任何时刻被杀死。因此,通常应该将 Activity 视为应用程序和用户可以讨论其“愿望”的“交互点”。始终由用户开始这个讨论。
2. 另一方面,有 Service,这些组件从不直接与用户交互。Service 的生命周期有保证,因此似乎是放置处理逻辑的正确位置。
因此,对于我在最开始描述的任务,公正地说:
1. 应该有一个登录活动。
2. 这个活动应该能够以4种模式运行:
- 清洁/刚开始/用户还没有按按钮。 - 用户刚刚按下按钮,我们正在与 Web API 交谈 - 这是长时间运行的任务,我们想显示一种 ProgressDialog。 - 我们设法与 Web API 交谈,并且它说一切都很好。在这里,我们可能会完成此活动并开始更有用的活动 - 用户最初想看到的活动。 - 我们没有设法与 Web API 交谈,或者它说用户凭据有问题。在这种情况下,我们正在显示错误消息。
3. 应该有一个负责与 Web API 交谈的 Service。
因此,这里有一个问题:
如何正确使 Activity 知道当前应处于哪个4种模式?
我考虑过的:
我牢记的主要要点如下:
1. Activity 的生命周期没有任何保证。当用户启动它们时,Activity 保证被启动,但之后它们可以在任何时刻被杀死。因此,通常应该将 Activity 视为应用程序和用户可以讨论其“愿望”的“交互点”。始终由用户开始这个讨论。
2. 另一方面,有 Service,这些组件从不直接与用户交互。Service 的生命周期有保证,因此似乎是放置处理逻辑的正确位置。
因此,对于我在最开始描述的任务,公正地说:
1. 应该有一个登录活动。
2. 这个活动应该能够以4种模式运行:
- 清洁/刚开始/用户还没有按按钮。 - 用户刚刚按下按钮,我们正在与 Web API 交谈 - 这是长时间运行的任务,我们想显示一种 ProgressDialog。 - 我们设法与 Web API 交谈,并且它说一切都很好。在这里,我们可能会完成此活动并开始更有用的活动 - 用户最初想看到的活动。 - 我们没有设法与 Web API 交谈,或者它说用户凭据有问题。在这种情况下,我们正在显示错误消息。
3. 应该有一个负责与 Web API 交谈的 Service。
因此,这里有一个问题:
如何正确使 Activity 知道当前应处于哪个4种模式?
我考虑过的:
使用
Activity
+AsyncTask
,由于AsyncTask
绑定特定的Activity
实例,一旦Activity
重新创建(例如设备方向更改),AsyncTask
就会绑定到“错误”的上下文中,因此无法正常工作。使用
Activity
+IntentService
,Activity
触发服务并在Intent
中提供“请求上下文”。一旦IntentService
完成,它使用sendBroadcast()
告诉Activity
当前进度。但是由于当IntentService
完成时,Activity
可能已经暂停,因此它将无法接收更新。与第二种情况类似,但使用
sendStickyBroadcast()
。这解决了丢失更新的问题,但Google认为这是一种不好的做法,因为会导致某种开销或其他问题。使用
IntentService
+ContentProvider
+Loader
。Activity
触发服务并在Intent
中提供“请求上下文”。请求上下文具有一个神奇的“请求令牌”,该令牌描述了“唯一的意图”,因此当“某事被完成”时,可以知道它是什么以及谁想要它。IntentService
通过将请求记录保存到数据库中(即请求令牌和状态(已开始)),然后开始处理来开始处理。处理完成后,它会将记录状态更新为“已完成”并在其中放置结果。同时,Activity
使用Loader
监听此记录。根据状态,它了解应以哪种模式运行。这种解决方案对所有情况都完美地工作,包括设备方向更改、离开活动、接听电话等,但感觉有点过度。
我想知道是否有更简单的解决方案。