异步任务在不同的活动中开始和结束
我想实现以下行为,但我不确定如何实现:
- 用户启动活动 活动
- 启动 AsyncTask
- 用户执行一些创建新活动的操作
- AsyncTask 完成并以某种方式将结果返回到新活动
有没有办法实现这种行为?
谢谢
I would like to achieve the following behaviour, but I'm not sure how:
- User start an activity
- Activity starts an AsyncTask
- User performs some action that creates a new activity
- The AsyncTask finishes and somehow returns the result to the new activity
Is there a way of achieving this behaviour?
Thank you
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
创建一个 Service ,它本身会生成自己的线程并进行后台处理。您可以将活动绑定到服务,以便在处理完成时回调活动。
Create a Service that itself spawns its own thread and does your background processing. You can bind your activities to the service so you can call back into an activity when your processing is complete.
我一直在使用克里斯建议的一种变体:
首先创建一个 IntentService ,这是最容易创建的一种
Service
。然后使用 SharedPreferences 来指示IntentService 并在您的
Service
和Activities
之间共享值。您的Activity
可以将自身注册为 OnSharedPreferenceChangeListener 为了知道您的服务何时完成工作和/或它关心的另一个 SharedPreference 已更改。使用
IntentService
,您所需要做的就是重写onHandleIntent
方法。 onHandleIntent 内的所有内容都将在后台线程上运行。I've been using a variation of what was suggested by Chris:
Start by creating an IntentService, which is the easiest kind of
Service
to create. Then use SharedPreferences to indicate the state of yourIntentService
and share values between yourService
andActivities
. YourActivity
can register itself as an OnSharedPreferenceChangeListener in order to know when your Service is done doing work and/or another SharedPreference it cares about has changed.With
IntentService
, all you need to do is override theonHandleIntent
method. Everything inside onHandleIntent will run on a background thread.这是一种完全按照您想要的方式进行操作的方法,假设结果是一个 int。您可以使用可分割对象来扩展此属性。也许,使用服务仍然是最好的选择。
1) 创建一个名为 Result 的类,它是结果的包装器。它必须实现 Parcelable 接口:
2) 现在,您可以使用 Result 对象作为第一个 Activity 的私有变量:
3) 在您的 firstActivity 中,您可以使用如下行启动 AsyncTask:
4) 您的 AsyncTask 可以通过以下方式创建:
5) 当您启动第二个 Activity 时,您可以将结果对象传递给第二个 Activity:
6) 最后,您可以从第二个 Activity 中使用以下代码获取结果:
有关 Parcelable 对象的更多详细信息,可以参见 Android 开发人员
This is a way to do exactly what you want, assuming that the result is an int. You can extend this property, using a parcelable object. Probably, using a Service is still the best choice.
1) Create a class, called Result, that is a wrapper for your result. It must implement the Parcelable interface:
2) Now, you can use a Result object as a private variable of the first activity:
3) In your firstActivity, you can start an AsyncTask with a line like this:
4) Your AsyncTask can be made in this way:
5) When you start the second Activity, you can pass your result object to the second activity:
6) Finally, from the second activity, you can obtain the result using this code:
For more details about parcelable object, can see Android Developer
Service 是一个组件,允许某些代码在外部拥有单独的生命周期无需与用户交互的活动。正如其他人提到的,这当然是值得考虑的一种选择。如果您同意的话, IntentService 是完成这项工作的最简单方法异步。
但是,您可以继续使用 AsyncTask,只需添加一些代码来表明它已“完成”。在这种情况下,如果您的应用程序被终止,后台工作不再重要,并且如果用户离开应用程序,您可以在该工作完成之前终止您的应用程序。另一种看待这一点的方法是,AsyncTask 的结果是否仅对这两个活动中的一个/两个活动重要,而不对外部活动重要。这是与需要服务的一个重要区别,服务再次提供活动之外的生命周期。
要传递数据,请查看此文档。有很多方法可以解决这个问题,但对于这种事情我更喜欢伪单例方法。 (我不喜欢使用 SharedPreferences 来传递数据,因为坦率地说,我不认为这就是该类的用途。与纯单例相比,我更喜欢这种伪单例方法,因为它更易于测试。Android 到处都使用单例方法我会在 Application 对象中创建对某种 AsyncTask 注册器类的引用。由于可以从两个活动访问 Application 对象,因此第一个活动可以向注册器注册您的 AsyncTask,第二个活动可以获取该 AsyncTask 并注册以侦听完成情况(如果尚未完成)。
A Service is a component that allows some code to have a separate lifetime outside of activities without interacting with the user. As others have mentioned, that's certainly one option to consider. If you go with that, IntentService is the easiest way to make the work asynchronous.
However, you could continue to use AsyncTask and just add some code to signal that it's "complete". This is the case when the background work no longer matters if your application is killed, and you're OK with your app being killed before this work completes if the user leaves the application. Another way to see this is if the result of the AsyncTask only matters to either/both of these two activities and not outside. This is an important difference in requirements from needing a Service which again, provides a lifetime outside of activities.
To pass the data, take a look at this doc. There are a lot of ways you could tackle this, but for this kind of thing I prefer a pseudo-singleton approach. (I don't like to use SharedPreferences to pass data, because frankly I don't think that's what the class is for. I prefer this pseudo-singleton approach over a pure singleton because it's more testable. Android uses the singleton approach all over the place though.) I'd create a reference to some sort of AsyncTask registrar class in the Application object. As the Application object is accessible from both activities, the first one can register your AsyncTask with the registrar and the second one can get that AsyncTask and register to listen for completion if it hasn't already finished.