注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

瘋人院

lunatic asylum

 
 
 

日志

 
 

构造快速响应的Android应用  

2010-05-02 17:56:07|  分类: android |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

“好”程序也会变成“坏”程序

在Android中,活动管理器和窗口管理器这两个系统服务负责监视应用程序的响应。当出现下列情况时,Android就会显示ANR对话框了:

  • 对输入事件(如按键、触摸屏事件)的响应超过5秒
  • 意向接受器(intentReceiver)超过10秒钟仍未执行完毕 


如何避免ANR

基于以上对ANR的定义,让我们来探寻一下产生ANR的原因,以及如何架构你的程序以力求避免ANR的发生。

通常情况下,Android应用程序完全运行在一个独立的线程中(例如main)。这就意味着,任何在主线程中运行的,需要消耗大量时间的操作都会引发ANR。因为此时,你的应用程序已经没有机会去响应输入事件和意向广播(Intent broadcast)。

因此,任何运行在主线程中的方法,都要尽可能的只做少量的工作。特别是活动生命周期中的重要方法如onCreate()和 onResume()等更应如此。潜在的比较耗时的操作,如访问网络和数据库;或者是开销很大的计算,比如改变位图的大小,需要在一个单独的子线程中完成(或者是使用异步请求,如数据库操作)。但这并不意味着你的主线程需要进入阻塞状态已等待子线程结束 -- 也不需要调用Therad.wait()或者Thread.sleep()方法。取而代之的是,主线程为子线程提供一个句柄(Handler),让子线程在即将结束的时候调用它(xing:可以参看Snake的例子,这种方法与以前我们所接触的有所不同)。使用这种方法涉及你的应用程序,能够保证你的程序对输入保持良好的响应,从而避免因为输入事件超过5秒钟不被处理而产生的ANR。这种实践需要应用到所有显示用户界面的线程,因为他们都面临着同样的超时问题。

IntentReciever在这方面有特殊的要求。它强调在执行期间,它只在后台完成很小的、细粒度的操作如保存一个设置或注册一个通知。所以如果其他在主线程中被调用的方法一样,IntentReciever也需要避免进行耗时的操作和计算。但与前面使用子线程的方法不同(因为IntentReceiver的生命周期很短 xing:子线程没结束它就结束了,就无法回调句柄了)。如果在接受一个意向广播(Intent broadcast)。的时候会产生潜在的耗时操作,你需要为此启动一个服务。顺便提醒一下,你也应该避免在意向接受器(Intent Reciever)中开始一个活动,因为这样会产生一个新的界面,夺取了正在运行的程序的焦点。如果你想在响应意向广播(Intent broadcast)。的时候向客户显示一些东西,那么就用通知管理器吧。 


进一步提高响应性

一般情况下,100到200毫秒是程序响应时间的阀值,超过了这个阀值使用者就会感到程序有延迟。因此,除了你需要避免产生ANR之外,还有几条建议能够使你的程序对用户的响应性更好。

  • 如果你的程序在后台处理用户的输入,给出一个你正在工作的提示(ProgressBar(进度条)和ProgressDialog(进度对话框)是很好的选择)
  • 如果是游戏,把计算步骤放在子线程中
  • 如果你的程序在开始的时候要进行一系列的初始化活动,最好显示一个闪现窗体(splash screen)或者尽可能的先快速渲染主界面,然后再通过异步的方式填充里面的内容。无论用哪种方法,你都要标示出目前正在执行哪些过程,以免用户以为程序已经卡死了。  







  评论这张
 
阅读(308)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017