Designing for Responsiveness翻译

来源:互联网 发布:2016社交媒体数据分析 编辑:程序博客网 时间:2024/06/05 07:26

 

 

为响应灵敏性设计:

代码可能通过各种性能测试,但是当用户使用时还是会需要漫长的等待,这些就是那种响应不够灵敏的应用——它们反应迟钝,挂起或冻住周期很长,或者要花很长时间来处理输入。在 Android 上,系统通过向用户显示一个称为应用无响应(ANR:Application Not Responding)的对话框来防止在一段时间内响应不够快。用户可以选择让应用继续,但是用户并不会想要每次都来处理这个对话框。因此应把你的应用设 计得响应灵敏,使得系统不必显示 ANR 给用户。

通常地,当不能响应用户输入时系统显示一个 ANR。例如,如果一个应用在 IO 操作(经常是网络访问)上阻塞了,那么主应用线程就会无法处理正在进行的用户输入事件。经过一段时间,系统认为应用已经挂起,向用户显示一个 ANR,让用户可以选择关闭。相同地,如果你的应用花太多的时间在构建详细的内存结构上,又或者在计算游戏的下一个动作上,系统会认为你的应用已经挂起。用上面的技术来保证这些计算是高效的一直都是很重要的,但是即使是最高效的代码运行也是需要花费时间的。

在这两种情况下,解决的办法通常就是创建一个子线程,在这个子线程上做你的大部分工作。这样让你的主线程(驱动用户接口事件循环)保持运行,并让你的代码 免于被系统认为已经冻住。因为这样的线程化通常都是在类级别上来完成的,所以你可以认为响应性能问题是一个类问题(与上面描述的方法级别的性能问题)。

这个文档讨论了 Android 系统是如何决定一个应用没有响应的,并提供了指引来保障你的应用是响应灵敏的。

1)是什么引发了 ANR?

Android 系统上,应用的响应灵敏性由 Activity Manager Window Manager system services所监控,当它监测到如下的其中一个条件时,Android 就会为特定的应用显示一个 ANR

5 秒内对输入事件无响应。

一个 BroadCastReceiver 10 秒内没有执行完毕。

怎样避免 ANR?

考虑到上面对 ANR 的定义,让我们来研究一下这是为什么会发生以及怎样最好的组织你的应用以避免 ANR

Android 应用正常是运行在一个单独的(如 main)线程中的,这就意味着在你应用主线程中正在做的需要花很长时间来完成的事情都能够激活 ANR 对话框。因为你的应用并没有给自己一个机会来处理输入事件或 Intent 广播。

因此任何运行在主线程中的方法应该做尽可能少的事情。特别地 Activitiy 在关键生命周期方法中如 onCreate() onResume()应当做 尽可能少的设置。潜在地的耗时长的操作(如网络或数据库操作,或高耗费数学计算如改变位图大小)应该在子线程里面完成(或以数据库操作为例,可以通过异步 请求)。尽管如此,这并不是说当等待子线程完成的过程中你的主线程必须被阻塞——你不必调用 Thread.wait() Thread.sleep() 恰恰相反,你的主线程应该为子线程提供一个 Handler,以便子线程完成时可以提交回给主线程。以这种方式来设计你的应用,将会允许你的主线程一直可以 响应输入,以避免由 5 秒钟的输入事件超时导致的 ANR 对话。这些做法同样应该被其它任何显示 UI 的线程所效仿,因为它们属于同样类型的超时。

IntentReciever 执行时间的特定限制限制了它们应该做什么:在后台执行的一些琐碎的工作如保存设置或注册通知。至于其它在主线程里被调用的方 法,在 BroadcastReceiver 中,应用应该避免潜在的长耗时操作或计算,而是应该用子线程来完成密集任务(因为 BroadcastReceiver 的生命周期是短暂的)。对 Intent broadcast 作出响应,你的应用应该启动一个 Service 来执行长耗时的动作。同样,你也应该避免从 Intent Receiver 中启动 Activity,因为它会产生一个新的屏,偷走任何用户正在运行的应用的焦点。对 Intent broadcast 作出的响应,假如你的应用需要向用户显示什么东西,应该用 Notification Manager 来完成。

增强响应灵敏性

通常,在一个应用中,100 200 微秒是一个让用户感觉到阻滞的阈值,因此这里有些小技巧让你用来使你的应用看起来响应更灵敏。

如果你的应用正在后台对用户输入作出响应,显示正在进行的进度(ProgressBar ProgressDialog 对此很有用)。特别是对于游戏,在子线程中做移动的计算。

如果你的应用有一个耗时的初始化过程,考虑用闪屏或尽可能快地渲染主界面并异步地填充信息。在这两种情况下你都应该表明进度正在进行,以免用户觉得你的应用被冻住了。

 

原创粉丝点击