arb*_*bee 3 android android-asynctask
API参考说明,
理想情况下,AsyncTasks应该用于短操作(最多几秒钟).
是否有一个doInBackground的问题,比如,线程池可能耗尽线程30秒?如果这就是原因,如果我确保我的应用程序永远不会有多个如此长时间运行的doInBackground同时执行,它会不会成为一个问题?
我相信AyncTasks通常仍然依赖于产生它们的前台活动堆栈,因此,例如,如果一个Activity产生AsyncTask,用户离开应用程序,然后操作系统缺少内存,它将终止活动的进程(包括仍在运行的AsyncTask),只是希望你恢复状态并重新开始,如果用户恢复/返回你的应用程序.
对于运行时间较长的任务,特别是只有一个或几个的排序,您可能需要一个服务,因为即使关闭应用程序的UI以节省内存,这些任务仍然可以保留.
免责声明:我有一段时间没有进行过Android编码,所以这个答案可能已经过时,或者基于对事物运作方式的错误理解.如果有最近经验的人可以发表评论确认,我会删除此警告; 如果他们知道这是正确的,那么欢迎高代表人员去编辑这一段.
@Walter Mundt给出的答案是正确的.不过,我想添加一个信息补充,并给出一个指向可用于长时间运行的AsyncTask的库的指针.
AsyncTasks专为在后台执行操作而设计.并且,是的,如果您的AsyncTask持续两年,那么您将面临两个不同的问题:
RoboSpice,我想介绍的库,由@Walter Mundt提出,使用后台服务来执行这种请求.它专为网络请求而设计(可能长期运行),但它可以很容易地适应执行与网络无关的长时间运行任务.我很乐意为它添加一个补丁.
这就是为什么AsyncTasks对于长时间运行的任务不利的原因.以下推理是对RoboSpice动机的改编:适用于解释为什么使用RoboSpice满足Android平台需求的应用程序.
AsyncTasks不遵循Activity实例的生命周期.如果在Activity中启动AsyncTask并旋转设备,则将销毁Activity并创建新实例.但AsyncTask不会死.它会继续生存直到它完成.
完成后,AsyncTask将不会更新新Activity的UI.实际上,它更新了之前不再显示的活动实例.这可能导致java.lang.IllegalArgumentException类型的异常:如果您使用findViewById来检索Activity内的视图,则View不会附加到窗口管理器.
将AsyncTasks创建为活动的内部类非常方便.由于AsyncTask需要在任务完成或正在进行时操纵Activity的视图,使用Activity的内部类似乎很方便:内部类可以直接访问外部类的任何字段.
然而,这意味着内部类将在其外部类实例上保存一个不可见的引用:Activity.
从长远来看,这会产生内存泄漏:如果AsyncTask持续很长时间,它会使活动保持"活着",而Android则希望摆脱它,因为它无法再显示.该活动不能被垃圾收集,这是Android在设备上保留资源的核心机制.
您可以使用一些变通方法来创建长时间运行的异步任务,并根据活动的生命周期管理其生命周期.您可以在活动的onStop方法中取消AsyncTask,也可以让异步任务完成,而不是松开其进度并将其重新链接到下一个活动实例.
这是可能的,我们展示了RobopSpice的动机,但它变得复杂,而且代码并不是真正的通用.此外,如果用户离开活动并返回,您仍将失去任务的进度.Loaders也出现了同样的问题,尽管它与上面提到的重新链接解决方法的AsyncTask相比更简单.
最好的选择是使用服务来执行长时间运行的后台任务.这正是RoboSpice提出的解决方案.同样,它专为网络设计,但可以扩展到非网络相关的东西.该库具有大量功能.
你可以通过信息图表在不到30秒的时间内了解它.
对于长时间运行的操作使用AsyncTasks确实是一个非常糟糕的主意.然而,它们适用于短期生活,例如在1或2秒后更新视图.
我鼓励您下载RoboSpice Motivations应用程序,它真正深入地解释了这一点,并提供了进行某些后台操作的不同方法的示例和演示.
如果您正在为非网络相关任务(例如没有缓存)寻找RoboSpice的替代方案,您还可以查看Tape.
| 归档时间: |
|
| 查看次数: |
4622 次 |
| 最近记录: |