可能会存在这样的情况,你写的代码通过了世界上所有的性能测试,但当用户尝试使用你的应用程序时,仍然让用户感到不爽。应用程序响应不够灵敏的地方包括——反映迟钝,挂起或冻结很长时间,或者需要花费很长的时间来处理输入。
在
Android上,如果你的应用程序有一段时间响应不够灵敏,系统会向用户显示一个对话框,这个对话框称作应用程序无响应
(ANR:Application Not
Responding)对话框。用户可以选择让程序继续运行,但是,他们在使用你的应用程序时,并不希望每次都要处理这个对话框。因此,在程序里对响应性
能的设计很重要,这样,系统不会显示ANR给用户。
一
般说来,如果应用程序不能响应用户输入的话,系统会显示一个ANR。例如,一个应用程序阻塞在一些I/O操作上(通常是网络访问),这时,应用程序的主线
程就不能再处理用户的输入事件。经过一定的时间后,系统认为应用程序已经挂起,并显示ANR来让用户选择杀死应用程序。
相似地,如果你的应用程序花费太多的时间来构建详细的内存结构,或者也许是在游戏里花费太多时间来计算下一步移动,这时,系统会认为你的应用程序已经挂起。因此,确保这些计算是高效的往往很重要,但即使是最高效的代码仍然需要花费时间来运行。
在
这两种情况下,解决的方法通常是创建一个子线程,然后在线程里做你的大部分工作。这能让主线程(驱动UI事件循环)保持运行,并阻止系统认为你的代码已经
冻结。因为这些线程通常是在类级别上完成的,因此,你可以认为响应性能问题是一个类的问题。(与基本性能相比而言,基本性能问题认为是方法级别的问题)
这篇文章将讨论Android系统如何判断一个应用程序处于无响应状态,并为保证应用程序的响应性提供向导。
这篇文章囊括这些主题:
- 什么引发了ANR?
- 如何避免ANR?
- 增强响应灵敏性
1)
什么引发了
ANR
?
在Android里,应用程序的响应性是由Activity Manager和Window Manager系统服务监视的。当它监测到以下情况中的一个时,Android就会针对特定的应用程序显示ANR:
- 在5秒内没有响应输入的事件(例如,按键按下,屏幕触摸)
- BroadcastReceiver在10秒内没有执行完毕
一个ANR对话框显示给用户
2)
如何避免
ANR
?
考虑上面的ANR定义,让我们来研究一下为什么它会在Android应用程序里发生和如何最佳构建应用程序来避免ANR。
Android应用程序通常是运行在一个单独的线程(例如,main)里。这意味着你的应用程序所做的事情如果在主线程里占用了太长的时间的话,就会引发ANR对话框,因为你的应用程序并没有给自己机会来处理输入事件或者Intent广播。
因
此,运行在主线程里的任何方法都尽可能少做事情。特别是,Activity应该在它的关键生命周期方法(如onCreate()和onResume())
里尽可能少的去做创建操作。潜在的耗时操作,例如网络或数据库操作,或者高耗时的计算如改变位图尺寸,应该在子线程里(或者以数据库操作为例,通过异步请
求的方式)来完成。然而,不是说你的主线程阻塞在那里等待子线程的完成——也不是调用Thread.wait()或是Thread.sleep()。替代
的方法是,主线程应该为子线程提供一个Handler,以便完成时能够提交给主线程。以这种方式设计你的应用程序,将能保证你的主线程保持对输入的响应性
并能避免由于5秒输入事件的超时引发的ANR对话框。这种做法应该在其它显示UI的线程里效仿,因为它们都受相同的超时影响。
IntentReceiver
执行时间的特殊限制意味着它应该做:在后台里做小的、琐碎的工作如保存设定或者注册一个Notification。和在主线程里调用的其它方法一样,应用
程序应该避免在BroadcastReceiver里做耗时的操作或计算。但不再是在子线程里做这些任务(因为BroadcastReceiver的生命
周期短),替代的是,如果响应Intent广播需要执行一个耗时的动作的话,应用程序应该启动一个Service。顺便提及一句,你也应该避免在
Intent
Receiver里启动一个Activity,因为它会创建一个新的画面,并从当前用户正在运行的程序上抢夺焦点。如果你的应用程序在响应Intent广
播时需要向用户展示什么,你应该使用Notification Manager来实现。
3)
增强响应灵敏性
一般来说,在应用程序里,100到200ms是用户能感知阻滞的时间阈值。因此,这里有一些额外的技巧来避免ANR,并有助于让你的应用程序看起来有响应性。
- 如果你的应用程序为响应用户输入正在后台工作的话,可以显示工作的进度(ProgressBar和ProgressDialog对这种情况来说很有用)。
- 特别是游戏,在子线程里做移动的计算。
- 如果你的应用程序有一个耗时的初始化过程的话,考虑可以显示一个Splash Screen或者快速显示主画面并异步来填充这些信息。在这两种情况下,你都应该显示正在进行的进度,以免用户认为应用程序被冻结了。
######################################
Android ANR分析
15:59:37 I/ActivityManager(130): ANR in process: com.android.email (last in com.android.email)
=>frameworks\base\services\java\com\android\server\am\ActivityManagerService.java
=>提示输出cpu信息
Annotation: keyDispatchingTimedOut
CPU usage:
=>frameworks\base\services\java\com\android\server\ProcessStats.java
=>输出cpu当前状态
=>/proc/loadavg 显示cpu负荷
=>1-分钟平均负载 / 5-分钟平均负载 / 15-分钟平均负载
Load: 4.37 / 4.55 / 3.97
=>cpu状态的时间段
CPU usage from 10987ms to 27ms ago:
=>/proc/state读取cpu的使用情况
=>http://linux.die.net/man/5/proc
=>user
=>kernel
=>iowait
=>irq -> 0
=>softirq -> 0
=>minor
The number of minor faults the process has made which have not required loading a memory page from disk.
=>major
The number of major faults the process has made which have required loading a memory page from disk.
system_server: 12% = 4% user + 7% kernel / faults: 1886 minor
m.android.email: 12% = 6% user + 5% kernel / faults: 2716 minor
sensorserver_ya: 7% = 0% user + 7% kernel
breeze.launcher: 3% = 0% user + 3% kernel / faults: 94 minor
ocess.msn.shell: 0% = 0% user + 0% kernel / faults: 38 minor
m.android.phone: 0% = 0% user + 0% kernel
alog: 0% = 0% user + 0% kernel
rpcrotuer_smd_x: 0% = 0% user + 0% kernel
rild: 0% = 0% user + 0% kernel
alog: 0% = 0% user + 0% kernel
events/0: 0% = 0% user + 0% kernel
port-bridge: 0% = 0% user + 0% kernel
TOTAL: 81% = 13% user + 25% kernel + 42% iowait
15:59:37 I/ActivityManager(130): Removing old ANR trace file from /data/anr/traces.txt
分享到:
相关推荐
4.2 为响应灵敏性设计 4.3 为无缝设计: 5. 多资源文件的引用 6. ANDROID 调试 LOGCAT 技巧 7. 用 ANDROID 运行最简单的C 程序 8. 开发技巧杂集 8.1 一些源于 CSS 的组合实现技巧 8.2 关于 SEARCH 搜索框的使用 . ....
通过《Android开发深入浅出》,读者不仅可以掌握Android开发的基本技能,还能了解到最新的开发实践和最佳实践,从而提升自己的专业素养,成为一名出色的Android开发者。这本书不仅是初学者的良师,也是资深开发者...
在Android开发领域,Eclipse是一款曾经非常流行的集成开发环境(IDE),它被广泛用于编写Android应用程序。本资源提供了一个简单的Android页面开发...通过实践和学习,开发者将逐渐熟悉Android的开发流程和最佳实践。
在Android与Java编程的世界里,开发者们通过编写代码来实现丰富的功能,打造各种各样的应用程序。Android是由Google主导...同时,不断关注Android的新特性和最佳实践,保持与时俱进,也是成为优秀开发者的重要步骤。
在Android系统中,广播接收器(Broadcast Receiver)是一种重要的组件,它允许应用程序对全局系统事件做出响应。...在实际开发中,开发者应谨慎处理这些广播,遵循最佳实践,以提高应用的稳定性和用户体验。
10. **最佳实践**:避免过度依赖手势,因为它们可能与其他系统或应用的手势冲突。同时,为用户提供明确的指示,让他们知道哪些手势可用以及如何使用。 总的来说,"GestureRecognise_android_"项目涵盖了Android手势...
最后,手册还涵盖了一些Android开发最佳实践,比如性能优化、支持多屏幕、UI设计的最佳实践、以及如何实现应用的响应灵敏性和流畅性设计。 整套手册旨在通过系统的、循序渐进的学习,帮助初学者掌握Android开发的...
综上所述,创建一个Android计步器应用涉及了传感器数据的获取与处理、用户界面设计、数据存储、权限管理、性能优化等多个方面,而提供灵敏度设置更是提升了应用的个性化和实用性。通过学习和实践这些知识点,开发者...
总之,"仿qq侧拉菜单"是一个专注于提供高质量用户体验的Android开发实践,它集成了许多Android UI设计的最佳实践,对于学习和提升Android应用的交互设计能力大有裨益。通过研究这个项目,开发者不仅可以了解如何实现...
在IT行业中,设计一个强大的顶部导航栏是提升用户体验的关键步骤之一。顶部导航栏,也称为头部导航或全局导航,通常位于...开发这样一个组件涉及到Android开发的相关技术和最佳实践,是构建优秀用户体验的重要一环。
在描述中提到的"很多大神推荐",这可能是指该源码实现了一些最佳实践或者优化,使得侧拉菜单在用户体验、性能和可定制性方面都有出色表现。例如,源码可能包含了以下特点: 1. **响应式滑动**:良好的侧拉菜单应该...
总之,“通讯录导航”项目涵盖了Android开发中的多个核心知识点,从数据存储、数据访问、UI设计到用户体验优化,是学习和实践Android应用开发的一个宝贵资源。通过深入研究此项目,开发者不仅可以提升Android编程...
在进行这些测试时,我们需要利用专业的测试工具和标准,如ISO 9241系列人机工程学标准,以及行业内的最佳实践。此外,还需要建立一套详尽的测试用例和测试报告,以便于问题的发现和改进。 通过这套全面的测试平台,...
React Native的核心理念是将Web开发的最佳实践带到移动平台,提供接近原生的性能和用户体验。 2. **JavaScript基础**:作为React Native的编程语言,JavaScript是一种广泛使用的解释型、类C语言,具有动态类型、...
在开发过程中,开发者会遵循Android的开发最佳实践,包括使用MVVM(Model-View-ViewModel)架构模式来分离业务逻辑和视图层,使用LiveData和Room库进行数据持久化,以及利用Android Jetpack组件提升开发效率和应用...
此外,Kotlin-Pokedex可能还包含了其他的最佳实践,如使用Kotlin的扩展函数和高阶函数来增强代码的可读性和简洁性,以及使用Android Data Binding库来简化视图和数据模型之间的绑定。 总的来说,Kotlin-Pokedex项目...
5. **最佳实践** - 在设计触摸控制时,考虑到不同屏幕尺寸和分辨率,建议使用百分比单位来定义控件大小,确保在不同设备上的一致性。 - 为了避免误触,合理设置触摸检测区域,避免覆盖到其他重要的游戏元素。 - ...
通过学习《C++ GUI编程与Qt 4》,开发者可以掌握Qt框架的精髓,提高GUI开发技能,同时也能了解C++在实际项目中的最佳实践。这本书对于想要从事桌面应用、移动应用或者嵌入式系统开发的程序员来说,是一份宝贵的资源...
GT911驱动程序应遵循最佳实践,避免内存泄漏,处理好异常情况,确保在硬件故障时能优雅地恢复。此外,定期更新驱动程序以获取厂商的安全补丁和性能提升。 总结,GT911触摸屏驱动程序是连接Linux系统与硬件的关键...