我正在通过各种实践来处理线程和AsyncTask的方向更改。我遇到了以下解决方案:
答案 0 :(得分:43)
上面提到的几种方法都是很好的做法,但我想我可以用简短的解释来总结它们。下面是目前用于http网络,异步工作/线程和缓存的一些最流行的库。
我个人目前正在使用 Otto , Loaders , Volley , Ormlite 以及基于的网络堆栈 Apache 和Service
。我希望在某些时候用 Volley , Retrofit 替换网络堆栈,最后可能 Robospice 。
我个人非常喜欢Otto和Volley
@Produce
能力保留最后一个事件,可以根据需要为任何新感兴趣的公共汽车订户生成答案 1 :(得分:7)
为什么不尝试Loaders
,特别是AsyncTaskLoader
?它们可通过Support Library用于预蜂窝,并与活动/片段生命周期完美匹配。以下是官方摘要:
- 每个活动和片段都可以使用它们。
- 他们提供异步数据加载。
- 他们会监控数据来源,并在内容发生变化时提供新结果。
- 在配置更改后重新创建时,它们会自动重新连接到上一个加载程序的游标。因此,他们不需要重新查询他们的数据。
答案 2 :(得分:4)
我们实际上正在使用 RoboSpice库。它仅在提供RequestListeners对象的服务上运行。
第一种方法的问题(保持AsyncTask之间的引用)是您可能会生成内存泄漏,因为当您的AsyncTasks保存您的活动引用时,它们将是不是垃圾收集。密切关注这个只是分析您的应用程序检查堆大小一遍又一遍地旋转相同的活动。你的堆应该在正常的参数中增长(有一段时间你的对象必须被垃圾收集与新对象同时存在)但是当GC运行时你的RAM分配应该落到你在开始。
因此,如果我必须推荐一些东西,那将是下一件事:
活动管理API调用和流程(使用RoboSpice,让de UI旋转) 使用retainInstance为true的Fragments中的简单屏幕。这让你可以直接将DTO传递给你的片段,你必须只管理顶层活动的状态。
答案 3 :(得分:3)
如果主要关注处理asyncTask,即每次更改方向时都不愿意下载数据,那么您可以尝试这样做 -
(1)在创建此类之前初始化任何值..
Boolean android_hacker = false;
(2)现在,当您完成在AsyncTask类上下载数据时,请将该值设置为true
android_hacker = true;
这里使用模型和数组适配器类维护所有数据
(3)现在每次改变方向,然后像这样检查
if( android_hacker = true ){
// Use your saved instance ..
}else{
// Download data as it is yet not downloaded ..
}
希望有所帮助......
答案 4 :(得分:2)
您可以通过多种方式尝试AsyncTask。如果你试图找到最佳实践,AsyncTask不是一个好的选择。 This answer解释了为什么不应该使用AsyncTask。他们建议您使用更好的方法来处理长时间运行的任务,RoboSpice。
我已经使用过这个库,我觉得值得尝试:尊重活动生命周期(方向改变),没有内存泄漏,支持多线程,缓存结果......它可以插拔长插请求任务使用缓存(但它不适用于非缓存请求)。
但我建议Google推出一个好方法:IntentService
和BroadcastReceiver
。您将在方向更改期间注册和未注册广播以接收数据结果。所有后台任务都将在IntentService中工作,并通过BroadcastReceiver通知您想要活动的任何内容。您可以尝试很多示例。这样的事情:http://mobile.tutsplus.com/tutorials/android/android-fundamentals-intentservice-basics/
<强>更新强>:
嗨R4j,重点是我的申请很安静。我要做 并行网络呼叫数。你使用IntentService的方法是 好,但不适合复杂的场景
我不认为这是一个问题。您可以使用IntentService执行任何操作,甚至是复杂的任务。如果您想要并行任务,您可以考虑使用多线程服务并通过Intent与活动进行通信。在服务和活动之间发送意图是安全和灵活的,这是Android方式。
如果你想缓存(通过文件下载,流,按数据库..)RoboSpice
是你的最佳选择
答案 5 :(得分:-3)
您可以尝试以下方法:
1)如果您的应用程序显式要求更改方向,只需在应用程序执行开始时禁用方向更改,这样您就可以避免任何与方向更改相关的崩溃或相关问题。
您可以在布局xml文件的最外层布局中使用以下行:
android:orientation="vertical"
(用于设置垂直方向)
2)您可以使用Asynctask在线程执行开始时设置或保留以前的方向值,如下所示(仅语法示例):
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
和
getResources().getConfiguration().orientation