Android开发中避免应用无响应的方法(ApplicationNotResponding、ANR)
App里发生的最糟糕的事是弹出应用无响应”ApplicationNotResponding”(ANR)对话框.本课讲的是如何保持应用响应,避免ANR。
什么触发ANR
通常,系统会在应用无法对用户输入响应时显示ANR。比如,如果一个应用在I/O操作上阻塞了(频繁请求网络)UI线程,系统无法处理用户输入事件。或者,在UI线程中,app花了大量时间在构建复杂的类,或在游戏中计算下一个动作。保证这些操作高效是很重要的,但最高效的代码也需要花费时间。
在任何情况下,都不要在UI线程执行耗时任务,取而代之的是创建一个工作线程,在这个线程里操作。这可以保持UI线程运行,阻止系统因为代码卡住而结束应用。
在Android里,ActivityManager和WindowManager系统服务监控着应用的响应能力。Android会在检测到以下情形中之一时,弹出ANR对话框:
1.未在5秒内对用户输入事件响应
2.BroadcastReceiver未在10秒内执行完
如何避免ANR
Android应用默认运行在单线程里,叫UI线程或主线程。这意味着,你的应用所有工作都在UI线程里,如果花费很长时间才能完成,会触发ANR,因为此时应用无法操控输入事件或广播。
因此,UI线程里的任何方法都应该尽可能地做轻量的工作,特别是Activity在生命周期方法,像onCreate(),onResume().潜在的耗时操作,像网络,数据库,或昂贵的计算(像改变图片大小)应该在工作线程里完成(或者在数据库操作案例里,通过一个异步请求)。
最高效的方法是为耗时操作使用AsyncTask类创建工作线程。继承AsyncTask实现doInBackground()方法来执行工作。要发送进度给用户,调用publishProgress(),会触发onProgressUpdate(),例子:
privateclassDownloadFilesTaskextendsAsyncTask<URL,Integer,Long>{
//Dothelong-runningworkinhere
protectedLongdoInBackground(URL...urls){
intcount=urls.length;
longtotalSize=0;
for(inti=0;i<count;i++){
totalSize+=Downloader.downloadFile(urls[i]);
publishProgress((int)((i/(float)count)*100));
//Escapeearlyifcancel()iscalled
if(isCancelled())break;
}
returntotalSize;
}
//ThisiscalledeachtimeyoucallpublishProgress()
protectedvoidonProgressUpdate(Integer...progress){
setProgressPercent(progress[0]);
}
//ThisiscalledwhendoInBackground()isfinished
protectedvoidonPostExecute(Longresult){
showNotification("Downloaded"+result+"bytes");
}
}
执行这个工作线程,只需要创建一个实例,调用execute():
尽管比AsyncTask更复杂,你可能还是想创建自己的线程或者HandlerThread类,如果这么做,你应该调用Process.setThreadPriority(THREAD_PRIORITY_BACKGROUND)设置线程优先线为”background”.如果没有,线程仍然会拖慢应用,因为它跟UI线程优先级相同。
如果你实现Thread或HandlerThread,确保UI线程没有因为等待工作线程执行完而阻塞。不要调用Thread.wait()或Thread.sleep(),而是提供一个Handler,供任务执行完后回调。如此设计,UI线程会保持响应,避免出现ANR对话框。
特别强调BroadcastReceiver的执行时间,意味着你要:分散工作到后台线程里,像保存设置或者注册Notification。执行密集任务(intensivetasks),应该用IntentService。
提示:你可以用StrictMode帮你找到在UI线程上潜在的耗时操作
相关文章
- android scaleanimation动画,【Android动画九章】-RotateAnimation(旋转动画)和ScaleAnimation(尺寸动画)…[通俗易懂]
- android bindservice方法,Android bindservice方法返回false
- strictmode android,Android 应用性能优化-StrictMode(严格模式)
- android进阶之了解Android系统与开机过程
- 测试android sdk是否安装成功,配置Android SDK
- Android Studio 安装配置教程 – Windows(详细版)
- android 定时器实例,Android定时器和Handler用法实例分析
- android系统中toast是什么_Android个人资料简单布局
- android触摸屏事件,Android Touch事件分析
- 在你的ios、android应用中嵌入官方版nodejs是什么感觉?
- eclipse配置android_零基础电脑初学者入门教程
- Android OpenGL ES 基础原理
- 【Android 应用开发】Ubuntu 下 Android Studio 开发工具使用详解 (旧版本 | 仅作参考)
- Android开发中遇到的问题(三)——eclipse创建android项目无法正常预览布局文件详解手机开发
- 合作汽车厂商:Android Auto与CarPlay将共存
- android检测耳机是否插入方法
- android使用Messenger绑定Service的多种实现方法
- Android触屏测试实例代码