可能会存在这样的情况,你写的代码通过了世界上所有的性能测试,但当用户尝试使用你的应用程序时,仍然让用户感到不爽。应用程序响应不够灵敏的地方包括——反映迟钝,挂起或冻结很长时间,或者需要花费很长的时间来处理输入。
在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-WatchDog`是一个专门为解决这个问题而设计的开源工具,它能够帮助开发者监控并处理ANR错误,从而提高应用的稳定性和用户体验。 `Android-ANR-WatchDog`的工作原理是通过创建一个后台线程,该线程不断...
这个库由Loopj开发,简化了网络交互的过程,使得开发者能够更高效地处理网络操作,而无需阻塞主线程,从而避免ANR(Application Not Responding)错误。在Android应用开发中,网络操作必须在后台线程进行,以确保...
华为LTE-ANR邻区自动优化 华为LTE-ANR邻区自动优化是基于自组织网络(SON)的 LTE 系统中的一个关键功能。ANR(AutomaticNeighbor Relation)功能可以自动发现漏配邻区,使 UE 顺利切换至原本系统中漏配邻区的目标...
这个库使得在Android应用中从服务器下载GIF文件变得简单,而不会阻塞主线程,从而避免ANR(Application Not Responding)错误。它支持多种请求方法,包括GET和POST,并提供了一套丰富的回调机制来处理网络请求的成功...
这种模式符合Android的推荐做法,避免了ANR(Application Not Responding)异常的发生。 总结,Android-Async-Http框架为Android开发者提供了一种简单、高效的网络通信解决方案。通过理解和掌握这个库,开发者可以...
这有助于防止因图片加载过程阻塞主线程而引发的ANR(Application Not Responding)错误。 2. **内存和磁盘缓存**:内存缓存使用LRU(Least Recently Used)策略,当内存不足时,自动清理最近最少使用的图片。磁盘...
异步加载意味着在不阻塞主线程的情况下加载图片,这样可以确保UI的流畅性,避免用户看到卡顿或者 ANR(应用程序无响应)的情况。UIL 使用了线程池进行图片的后台加载,通过配置不同的线程策略,如基于设备性能动态...
3. **异步任务**:如何使用AsyncTask进行后台处理并更新UI,同时避免ANR(Application Not Responding)问题。 4. **传感器和位置服务**:演示如何获取和处理来自GPS、加速度计等传感器的数据。 5. **通知栏优化**:...
- Android应用的网络请求应在后台线程中执行,以避免ANR(应用无响应)错误。 - 使用`AsyncHttpClient`时,库内部会自动处理线程切换,无需开发者手动创建线程池。 4. **进度更新**: - `android-async-http`库...
《Bugsnag-Android-NDK:从原生Android C/C++代码中处理错误》 在移动应用开发中,尤其是在Android平台,原生C/C++代码的使用是常见且必要的,因为它们能提供更高的性能和更低级别的硬件访问权限。然而,这种编程...
在"asmack-android-19-source-0.8.10"这个压缩包中,包含了ASMACK针对Android 19(即KitKat版本)的源代码,版本号为0.8.10。这个版本的源码提供了对Android系统特性的优化,以适应其运行环境,并且在性能和稳定性上...
### Android之ANR的原理(Input, Service, Broadcast) #### ANR概述 ANR(Application Not Responding)是指Android应用程序在执行过程中响应超时的一种异常状态。当应用程序长时间不响应用户的操作时,系统会提示...
它在后台线程执行网络操作,避免了主线程(UI线程)的阻塞,防止应用出现ANR(Application Not Responding)错误。 2. **请求构建**:在发起请求前,需要设置URL、HTTP方法(GET、POST等)、请求头和请求体等参数。...
这个框架极大地简化了在Android应用中进行HTTP请求的操作,允许开发者在后台线程执行网络操作,从而避免了主线程因网络I/O而引发的ANR(Application Not Responding)错误。以下是对这个框架的详细介绍和相关知识点...
这个名为"RxJava-Android-Samples"的开源项目,为开发者提供了一系列实际运行的示例,帮助我们深入理解并熟练运用RxJava。本文将基于这个项目,对RxJava在Android环境下的核心概念、使用场景和最佳实践进行详尽的...
在Android中,如果在主线程中执行耗时操作,如网络请求或图片解码,会阻塞UI更新,导致应用无响应(ANR)。为避免这种情况,我们需要将这些任务放在后台线程执行,而Universal-Image-Loader库就提供了这样的功能。 ...
这有助于避免直接操作UI线程导致的ANR(Application Not Responding)问题。 三、集成与使用 要在项目中使用`android-support-v4.jar`,首先需要在Gradle依赖中添加以下代码: ```groovy dependencies { ...
ANR是Android应用程序无响应的缩写,当主线程在5秒内无法处理输入事件或BroadcastReceiver在10秒内无法完成工作时,系统会弹出ANR对话框。避免ANR的关键在于避免主线程的阻塞,将耗时操作放在子线程或Service中执行...
在Android系统中,ANR(Application Not Responding)是一个常见的问题,它表示应用程序无响应,通常出现在用户界面长时间无法交互时。在Android 7.0版本中,框架引入了一种新特性,即自动关闭ANR对话框,并允许...
这遵循了Android的UI线程最佳实践,防止了ANR(Application Not Responding)错误的发生。 2. **简单易用的API** 使用Android-Async-Http,开发者可以通过简洁的API发送GET、POST等HTTP请求。例如,只需几行代码就...