ANR-[Android_YangKe]

什么是 ANR

ANR 是指应用程序无响应(Application Not Responding)

在Android中,该系统通过显示一个对话框来防止在一段时间内响应不足的应用程序,该对话框显示您的应用程序已停止响应,例如图1中的对话框。此时,您的应用程序在相当长的一段时间内不会有反应的时间,因此系统为用户提供退出应用程序的选项。

本文档描述了Android 系统如何确定应用程序是否没有响应,并提供了确保应用程序保持响应的准则


yangke.png

ANR 如何触发

通常,如果应用程序无法响应用户输入,系统将显示 ANR。 例如,如果应用程序阻塞 UI 线程上的某些 I / O操作(通常是网络访问),因此系统无法处理传入的用户输入事件。

在您的应用程序执行潜在的长度操作的任何情况下,您不应该在 UI 线程上执行工作,而是创建一个工作线程并执行大部分工作,这样可以保持 UI 线程(驱动冻结的线程) 这样的线程通常是在类级别上完成的,你可以将响应性视为一个类问题(与基本代码性能进行比较,这是一个方法级的关注点)

在 Android中,应用程序响应由 Activity Manager 和 Window Manager 系统服务进行监控。 当检测到以下情况之一时,Android 将显示特定应用程序的 ANR 对话框:

  • 在5秒内没有响应输入事件(如按键或屏幕触摸事件)
  • 广播接收器在10秒内尚未完成执行

注 ANR 对话框并不总是显示给用户,但出现 ANR 对话框的应用一定存在性能问题。

怎样避免 ANR

默认情况下,Android 应用程序通常在单线程上运行,“UI线程”或“主线程”)。这意味着您的应用程序在 UI 线程中执行的任务需要很长时间才能触发 ANR 对话框,因为您的应用程序并没有给自己一个处理输入事件或意图广播的机会。

因此,在 UI 线程中运行的任何方法都应该尽可能少的工作在该线程上。特别地,Activity 应尽可能少地在关键的生命周期方法中设置,如 onCreate()和 onResume()。潜在的长时间运行操作(如网络或数据库操作)或主线程进行大量计算(如调整位图大小)应在工作线程中完成(或者在数据库操作的情况下,通过异步请求)。

使用 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");
}
}

要执行这个工作线程,只需创建一个实例并调用 execute():

new DownloadFilesTask().execute(url1, url2, url3);

虽然它比 AsyncTask 更复杂,但您可能想要创建自己的 Thread 或HandlerThread 类。如果这样做,您应该通过调用 Process.setThreadPriority()并传递 THREAD_PRIORITY_BACKGROUND 来将线程优先级设置为“background”优先级。如果你没有以这种方式将线程设置为较低优先级,那么线程可能会减慢你的应用程序,因为默认情况下它与 UI 线程的优先级相同。

如果您实现 Thread 或 HandlerThread,请确保您的UI线程在等待工作线程完成时不会阻塞 - 请勿调用 Thread.wait()或 Thread.sleep()。等待工作线程完成时,您的主线程不应阻塞,而是为其他线程提供一个处理程序,以便在完成后发回。以这种方式设计您的应用程序将允许您的应用程序的UI线程保持对输入的响应,从而避免由5秒输入事件超时引起的 ANR 对话框。

BroadcastReceiver 执行时间的具体约束强调了广播接收者要做的事情:在后台工作量小,如保存设置或注册通知。所以与 UI 线程中调用的其他方法一样,应用程序应避免在广播接收器中潜在的长时间运行的操作或计算。但是,如果需要采取潜在的长时间运行操作来响应意向广播,而不是通过工作线程进行密集的任务,则应用程序应启动 IntentService。

BroadcastReceiver 对象的另一个常见问题是当它们执行得太频繁时发生。频繁的后台执行可以减少其他应用程序可用的内存量。有关如何有效启用和禁用 BroadcastReceiver 对象的更多信息,请参阅按需处理广播接收器。

提示:您可以使用 StrictMode
来帮助您找到可能长时间运行的操作,例如网络或数据库操作,您可能会意外地在主线程上执行此操作。

增强反应速度

通常,100到200ms是用户在应用程序中感觉到缓慢的阈值。 因此,这里还有一些额外的提示,除了您应该做什么以避免 ANR,使您的应用程序似乎响应用户:

  • 如果您的应用程序在后台执行响应用户输入的工作,则显示正在进行进度(例如,在用户界面中使用 ProgressBar)。
  • 对于游戏具体来说,做一个工作线程的移动计算。
  • 如果您的应用程序具有耗时的初始设置阶段,请考虑显示启动屏幕或尽快呈现主视图,指示正在进行加载并异步填充信息。 在这两种情况下,您应该以某种方式指出进展情况,以免用户察觉到应用程序被冻结。
  • 使用 SystraceTraceview 等性能工具来确定应用程序响应速度的瓶颈。

ANR 日志

当设备上的 /data/anr/traces.txt 文件中遇到 ANR 时,Android 会存储一些跟踪信息。 您可以通过以 root 用户身份在设备上启动 shell 会话从模拟器获取文件,如以下命令行示例所示:

adb root
adb shell
cat /data/anr/traces.txt 

最好的学习网站:https://developer.android.com/topic/performance/vitals/anr.html#fix_the_problem

ps: 喜欢有帮助的话: 双击、评论、转发,动一动你的小手让更多的人知道!关注 帅比-杨

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,294评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,780评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,001评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,593评论 1 289
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,687评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,679评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,667评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,426评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,872评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,180评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,346评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,019评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,658评论 3 323
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,268评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,495评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,275评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,207评论 2 352

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,647评论 18 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,020评论 25 707
  • 当Android应用程序的UI线程阻塞时间过长时,会触发“应用程序不响应”(ANR)错误。如果应用程序处于前台,系...
    Cfvdjnl阅读 1,058评论 0 2
  • 土家歌儿唱七回 善良的土家人,有趣的石柱故事,值得诉说,值得追忆。 第1回——过年歌 牛大哥呀你莫贪, 今日同吃团...
    秭归秀才9条命儿阅读 447评论 0 1
  • 失败了 心伤了 失恋了 心痛了 时光流逝 如水漫过 青涩记忆 涌入脑海 心痛了 想忘记 心累了 想休息 心~~有一...
    雪之道阅读 162评论 1 1