有这样一种情况:即使你写的代码通过世界上的每一个性能测试,但程序在特定的操作和重要的阶段仍然让人感觉运行缓慢,或者需要花很长时间处理输入。这种发生在你的app里的糟糕的响应是“Application Not Responding(ANR)”对话框。
Figure 1. An ANR dialog displayed to the user.
在Android里,当app一段时间无响应时,系统会弹出一个对话框,告诉你,你的app长时间没响应。如图一。
出现该对话框,表明你的app已在合理的一段时间内已没有响应用户操作,因此,系统弹出该对话框窗口,给用户选择是否退出应用。设计高响应的应用以便于系统从不展示ANR对话框给用户是很关键的。
这篇文档描述了android系统如何判断app是否是ANR的,也提供了相关如何避免ANR的建议。
What Triggers ANR?
一般地,如果app不能响应用户的输入,系统将展示ANR。例如,应用在UI线程里阻塞在I/O操作(频繁的网络访问)导致系统不能处理来自用户的输入事件。又或者在在游戏app里在UI线程上进行耗时的位置计算(从一个位置移动到另一个位置)。
在你的app里任何潜在的耗时操作,你都不应该在UI线程里执行。而是产生一个非UI线程,在U该非UI线程里进行耗时操作。这确保了你的UI线程(能循环驱动用户界面事件)运行,并且避免了系统认为你的应用已被阻塞。因为如此的线程实现在一个类级别上,你可以认为app响应的问题是类级别上的问题(相比于基本的代码性能问题,代码性能问题可以认为是方法级别上的问题)。
在Android里,Activity Manager 和 Window Manager 系统服务会监控app是否有ANR发生并当监测到有ANR发生时展示ANR对话框。下面两种情境将触发ANR:
1. 5秒内不能响应用户输入(例如:键盘按下或者屏幕触摸事件)
2. BroadcastReciever在10秒内不能执行完成
How to Avoid ANRs
Android应用一般情况下默认运行在一个单一线程上(称为UI线程或者主线程)。这意味着任何在你的UI线程里做的耗时操作都能触发ANR。因为在这种情况下,你的app将没有机会处理输入事件和广播意图。
因此,任何在UI线程里运行的方法都尽量不要做耗时操作。特别地,在activity的关键生命周期方法里例如像onCreate()和onResume()不要进行耗时操作。潜在的耗时操作例如网络和数据库操作、复杂的耗时计算(例如:重新计算bitmap的大小)都应该放在子线程里。
产生子线程的最有效的方式用AsyncTask类。简单地继承AsyncTask,然后实现doInBackground()方法,在该方法里进行耗时操作。为了提交进度改变给用户,你能调用publishProgress().该方法会回调onProgressUpdate()方法。
由于onProgressUpdate()运行在UI线程。你能通知用户更新结果。例如:
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
// Do the long-running work in here
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
}
// This is called each time you call publishProgress()
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
// This is called when doInBackground() is finished
protected void onPostExecute(Long result) {
showNotification("Downloaded " + result + " bytes");
}
}
为了执行子线程,简单地产生AnsyncTask的实例,调用execute()方法。
new DownloadFilesTask().execute(url1, url2, url3);
有时你可能需要自己产生Thread或者HandlerThread类,虽然这比起AnsyncTask更复杂点。如果你这样做,你需要设置线程优先级为“background”优先级。通过Process.setThreadPriority()来设置线程优先级,传递参数THREAD_PRIORITY_BACKGROUND即可。如果你不设置你的线程优先级为THREAD_PRIORITY _BACKGROUND,该线程能然可能放慢你的应用。因为它默认和你UI线程一个优先级。
如果,你实现Thead或者HandlerThread,确保你的UI线程在等待子线程运行结果完成时不要被阻塞--即在主线程里不要调用Thread.wait()或者Thread.sleep().为了避免阻塞你的主线程,你的主线程应该给子线程提供一个Handler用于通知UI线程操作执行完成。按这种方式设计你的应用将能让你的UI线程能响应用户输入并且避免5秒输入响应超时而弹出ANR。
Android专门针对BroadcastReceiver的执行时间限制主要是为了强调广播接收者主要用于做如下事情:小的、零碎离散的后台工作例如:保存设置或者注册Notification等。像其他在UI线程里调用的方法一样,广播接收者里也应该避免潜在的长时间操作或者计算。但是不同于把耗时操作放在子线程里,为了响应一个耗时操作的广播意图,你的应用应该开启一个intentService。
Tip:你能用StrictMode帮助你发现不小心放在UI线程里的潜在的耗时操作(例如网络或者数据库操作)。
Reinforce Responsiveness
一般地,100-200ms是用户感知缓慢的时间分割点。如此,下面是一些为了避免ANR你应该遵循的一些额外的建议:
1.为了响应用户操作你的app将一些操作放在了后台,你应该给用户显示进度条(例如在你的UI上放一个ProgressBar)。
2.特别地开发游戏应用时,位置计算(例如移动)放在后台进程。
3.如果你的应用有一个长时间初始化阶段,可以考虑显示一个渐进缓冲的屏幕或者尽可能快的渲染主界面,已表明加载正在进行,然后异步填充数据。不管如何,你都应该表明你的app正在加载,以免让用户
觉得你的app好像死掉了一样。
4.使用如Systrace和Traceview这样的性能工具分析你的app响应的瓶颈。
相关推荐
【Android性能优化典范 - 第6季 - 胡凯】主要涵盖了Android应用性能优化的关键方面,特别是关于程序启动时间和安装包大小的优化。以下是详细的知识点解析: 1. **程序启动时间优化**: - **启动时间的重要性**:...
5. **资源效率**:`Android-ANR-WatchDog`设计得非常轻量,对设备资源的占用极小,不会影响应用的整体性能。 6. **集成简单**:只需在项目中引入库,配置好参数,就可以轻松集成到任何Android应用中。 7. **源代码...
【Android性能优化】是Android开发中的重要环节,涵盖了多个关键领域,包括ANR问题解析、crash监控方案、启动速度与执行效率优化、内存优化、耗电优化、网络传输与数据存储优化以及APK大小优化。 **ANR问题解析**是...
本专题将深入探讨Android性能优化的关键知识点,帮助开发者提升应用的运行效率和用户体验。 首先,我们要理解Android性能优化的基本原则:减少资源消耗、提高响应速度、降低内存占用以及提升电池续航。在Java编程...
Android性能优化 ANR 分析指导文档 一、什么是 ANR? 在 Android 系统中,应用程序的响应性是由 Activity Manager 和 WindowManager 系统服务监视的。当应用程序出现以下情况时,Android 就会针对特定的应用程序...
ANR-WatchDog是一款专为Android系统设计的开源项目,其主要目的是监控并处理应用程序无响应(ANR:Application Not Responding)的问题。在Android操作系统中,当一个应用执行主线程上的操作超过5秒钟而未给出响应时...
UI性能优化是Android开发中的核心议题。开发者需要关注渲染性能,包括帧率(FPS)、布局层次、过度绘制和内存使用等。对于帧率,目标是保持60 FPS,以提供流畅的用户体验。如果出现卡顿,可能是因为主线程负载过高,...
4. **Android性能优化**: - 内存优化:避免内存泄漏,使用LeakCanary检测内存泄漏。 - 性能监控:使用Systrace、Traceview、HierarchyViewer等工具进行性能分析。 - UI流畅度:理解60fps的概念,避免ANR...
避免ANR的方法: 1. **使用AsyncTask**:对于耗时操作,应放在后台线程进行,如使用AsyncTask,这样不会阻塞主线程。 2. **IntentService**:处理耗时任务时,推荐使用IntentService,它会在单独的工作线程中运行,...
《Android 360°全方面性能调优》是一本深度探讨Android系统性能优化的宝典,涵盖了设计思想、代码优化、程序性能、内存管理、功耗控制、网络通信、应用打包、屏幕适配、启动速度、流畅度、ANR问题、崩溃监控、OOM...
在Android应用开发中,性能优化是一项至关重要的任务,它直接影响到用户的体验和应用程序的市场竞争力。"Android应用性能优化最佳实践"这本书深入探讨了如何提升Android应用的性能,以下是一些核心知识点的总结: 1...
高效的图片加载不仅能够提升用户体验,还能优化应用性能,避免内存泄露等问题。Android-Universal-Image-Loader(UIL)就是这样一款强大的开源库,它专门用于处理Android应用中的图片异步加载和缓存问题。 1. 图片...
ANR优化是Android性能优化中一个非常重要的方面。ANR的解决方案包括: * 避免死锁的出现,使用子线程来处理耗时操作 * 避免主线程qurey provider,不要滥用sharePreference的commit()方法 * 各大组件生命周期中也应...
那么,如何避免ANR的发生呢?开发者可以通过以下方法优化应用性能,从而减少ANR问题的出现: 1. 避免在主线程中进行耗时操作,比如网络请求、大数据处理、复杂的计算等操作,应使用异步任务处理。 2. 使用多线程或...
这种模式符合Android的推荐做法,避免了ANR(Application Not Responding)异常的发生。 总结,Android-Async-Http框架为Android开发者提供了一种简单、高效的网络通信解决方案。通过理解和掌握这个库,开发者可以...
Android性能优化技术的应用可以提高 Android 应用程序的性能,避免应用程序出现卡顿、崩溃等问题。本文通过研究体重管理 APP 的开发过程中遇到的性能问题,并探讨了这些问题的解决方案,旨在提高 Android 应用程序的...
8. **性能优化**: - ANR(应用无响应)的避免和处理。 - 帧率分析、内存泄漏检测和内存优化。 - CPU和GPU优化,减少过度绘制。 9. **组件间通信**: - BroadcastReceiver:广播接收者,处理系统或自定义广播...
这个库使得在Android应用中从服务器下载GIF文件变得简单,而不会阻塞主线程,从而避免ANR(Application Not Responding)错误。它支持多种请求方法,包括GET和POST,并提供了一套丰富的回调机制来处理网络请求的成功...
综上所述,Android图片压缩解决方案涉及多个层次和方法,开发者需要根据应用的实际需求和性能要求,选择合适的策略和工具,以确保图片加载的高效性和稳定性,避免ANR的发生。同时,持续关注和学习新的库和技术,也是...