ANR问题分析总结

前言

ANR(Application Not Responding)应用程序无响应。如果你应用程序在 UI 线程被阻塞太长时间,就会出现 ANR,通常出现 ANR,系统会弹出一个提示提示框,让用户知道,该程序正在被阻塞,是否继续等待还是关闭。

ANR类型

出现ANR的一般有以下几种类型:

类型 说明 logcat日志关键字
KeyDispatchTimeout(常见) input事件在5S内没有处理完成发生了ANR Input event dispatching timed out
BroadcastTimeout 前台Broadcast:onReceiver在10S内没有处理完成发生ANR
后台Broadcast:onReceiver在60s内没有处理完成发生ANR
Timeout of broadcast BroadcastRecord
ServiceTimeout 前台Service:onCreate,onStart,onBind等生命周期在20s内没有处理完成发生ANR
后台Service:onCreate,onStart,onBind等生命周期在200s内没有处理完成发生ANR
Timeout executing service
ContentProviderTimeout ContentProvider 在10S内没有处理完成发生ANR timeout publishing content providers

一、导出并查看 ANR 日志

执行命令:

adb bugreport bugreport.zip
adb pull /data/debuglogger/mobilelog

可以导出设备所有 bug 日志,执行命令后,在指定文件夹内得到一个 zip 文件,将文件解压后打开,文件目录如下所示:

其中,设备的 anr 日志会保存在该路径下:C:\Users\xxx\Desktop\bugreport\FS\data\anr,如图:

另外,该文件 C:\Users\xxx\Desktop\bugreport\bugreport-100110603-TP1A.220624.014-2022-10-12-09-49-59.txt 内也有有 anr 日志的打印,我们可以通过以下关键词搜索该文件的一些异常信息,如:

  • "main" prio= 搜索 anr 相关信息
  • beginning of crash 搜索 crash 相关信息
  • CPU usage from 搜索 cpu 使用信息

二、ANR 日志如何分析

一个 ANR 日志,会包含当前设备中所有进程的使用情况,每个进程开头都会
----- pid 17376 at date ----- 来开头,
----- end 17376 ----- 来结尾,
如下所示:

----- pid 17376 at 2022-10-11 09:52:04.264664750+0800 -----
Cmd line: com.android.vending
...
...
...
----- end 17376 -----

另外,每个进程日志中都会有一些进程内存相关的信息,如:

----- pid 17376 at 2022-06-16 16:56:04 -----
Cmd line: com.android.vending
...
...
Total number of allocations 274640   // 进程创建到现在一共创建了多少对象
Total bytes allocated 13MB   // 进程创建到现在一共申请了多少内存
Total bytes freed 5821KB   // 进程创建到现在一共释放了多少内存
Free memory 4562KB   // 空闲内存(可用内存)
Free memory until GC 4562KB   // GC前的空闲内存
Free memory until OOME 248MB   // OOM之前的可用内存,当这个值很小的时候,已经处于内存紧张状态,应用可能占用了过多的内存
Total memory11MB  // 当前总内存(已用+可用)
Max memory 256MB  // 进程最多能申请的内存 
...
----- end 17376 -----

另外,每个进程日志中都会有进程堆栈信息,堆栈信息非常重要,它展示了发生 ANR 的进程当前的所有线程状态。如下所示:

----- pid 17376 at 2022-06-16 16:56:04 -----
Cmd line: com.android.vending
...
suspend all histogram:  Sum: 141.888ms 99% C.I. 0.012ms-91.709ms Avg: 4.892ms Max: 100.514ms
DALVIK THREADS (56):
"Signal Catcher" daemon prio=10 tid=6 Runnable
  | group="system" sCount=0 ucsCount=0 flags=0 obj=0x132c08e0 self=0xb400007dceb186f0
  | sysTid=17386 nice=-20 cgrp=default sched=0/0 handle=0x7c47bdbcb0
  | state=R schedstat=( 44080464 23366075 22 ) utm=3 stm=0 core=2 HZ=100
  | stack=0x7c47ae4000-0x7c47ae6000 stackSize=991KB
  | held mutexes= "mutator lock"(shared held)
  native: #00 pc 00000000005376cc  /apex/com.android.art/lib64/libart.so (art::DumpNativeStack(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, int, BacktraceMap*, char const*, art::ArtMethod*, void*, bool)+128) (BuildId: 56e704c544e6c624201be2ab4933e853)
  native: #01 pc 00000000006f0e24  /apex/com.android.art/lib64/libart.so (art::Thread::DumpStack(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, bool, BacktraceMap*, bool) const+236) (BuildId: 56e704c544e6c624201be2ab4933e853)
  native: #02 pc 00000000006fe6b0  /apex/com.android.art/lib64/libart.so (art::DumpCheckpoint::Run(art::Thread*)+208) (BuildId: 56e704c544e6c624201be2ab4933e853)
  native: #03 pc 0000000000364174  /apex/com.android.art/lib64/libart.so (art::ThreadList::RunCheckpoint(art::Closure*, art::Closure*)+440) (BuildId: 56e704c544e6c624201be2ab4933e853)
  native: #04 pc 00000000006fce50  /apex/com.android.art/lib64/libart.so (art::ThreadList::Dump(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, bool)+280) (BuildId: 56e704c544e6c624201be2ab4933e853)
  native: #05 pc 00000000006fc844  /apex/com.android.art/lib64/libart.so (art::ThreadList::DumpForSigQuit(std::__1::basic_ostream<char, std::__1::char_traits<char> >&)+292) (BuildId: 56e704c544e6c624201be2ab4933e853)
  native: #06 pc 00000000006d5914  /apex/com.android.art/lib64/libart.so (art::Runtime::DumpForSigQuit(std::__1::basic_ostream<char, std::__1::char_traits<char> >&)+184) (BuildId: 56e704c544e6c624201be2ab4933e853)
  native: #07 pc 00000000006e19c0  /apex/com.android.art/lib64/libart.so (art::SignalCatcher::HandleSigQuit()+468) (BuildId: 56e704c544e6c624201be2ab4933e853)
  native: #08 pc 0000000000573e40  /apex/com.android.art/lib64/libart.so (art::SignalCatcher::Run(void*)+264) (BuildId: 56e704c544e6c624201be2ab4933e853)
  native: #09 pc 00000000000c1e40  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+208) (BuildId: 037ccd4f6c32456866be69c5a0a56591)
  native: #10 pc 0000000000054b50  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: 037ccd4f6c32456866be69c5a0a56591)
  (no managed stack frames)
"main" prio=5 tid=1 Waiting
  | group="main" sCount=1 ucsCount=0 flags=1 obj=0x720c41e8 self=0xb400007dceb13380
  | sysTid=17376 nice=0 cgrp=default sched=0/0 handle=0x7f1ae4f4f8
  | state=S schedstat=( 520024534 625550234 691 ) utm=28 stm=23 core=5 HZ=100
  | stack=0x7fea717000-0x7fea719000 stackSize=8188KB
  | held mutexes=
  at jdk.internal.misc.Unsafe.park(Native method)
  - waiting on an unknown object
  at java.util.concurrent.locks.LockSupport.park(LockSupport.java:194)
  at aidy.get(PG:5)
  at aihp.c(PG:1)
  at gdu.az(PG:2)
  at gge.j(PG:33)
  - locked <0x07048dde> (a com.google.android.finsky.application.classic.ClassicApplication)
  at gge.onCreate(PG:3)
  at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1266)
  at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6826)
  at android.app.ActivityThread.-$$Nest$mhandleBindApplication(unavailable:0)
  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2171)
  at android.os.Handler.dispatchMessage(Handler.java:106)
  at android.os.Looper.loopOnce(Looper.java:201)
  at android.os.Looper.loop(Looper.java:288)
  at android.app.ActivityThread.main(ActivityThread.java:7941)
  at java.lang.reflect.Method.invoke(Native method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:569)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1015)
 ...
"Jit thread pool worker thread 0" daemon prio=5 tid=8 Native
  | group="system" sCount=1 ucsCount=0 flags=1 obj=0x132c09d0 self=0xb400007dceb43e40
  | sysTid=17389 nice=9 cgrp=default sched=0/0 handle=0x7c478e1cb0
  | state=S schedstat=( 46231998 254143847 68 ) utm=3 stm=0 core=7 HZ=100
  | stack=0x7c477e2000-0x7c477e4000 stackSize=1023KB
  | held mutexes=
  native: #00 pc 000000000004f66c  /apex/com.android.runtime/lib64/bionic/libc.so (syscall+28) (BuildId: 037ccd4f6c32456866be69c5a0a56591)
  native: #01 pc 000000000047cc80  /apex/com.android.art/lib64/libart.so (art::ConditionVariable::WaitHoldingLocks(art::Thread*)+140) (BuildId: 56e704c544e6c624201be2ab4933e853)
  native: #02 pc 000000000047cb18  /apex/com.android.art/lib64/libart.so (art::ThreadPool::GetTask(art::Thread*)+120) (BuildId: 56e704c544e6c624201be2ab4933e853)
  native: #03 pc 0000000000619810  /apex/com.android.art/lib64/libart.so (art::ThreadPoolWorker::Run()+136) (BuildId: 56e704c544e6c624201be2ab4933e853)
  native: #04 pc 00000000006196f0  /apex/com.android.art/lib64/libart.so (art::ThreadPoolWorker::Callback(void*)+160) (BuildId: 56e704c544e6c624201be2ab4933e853)
  native: #05 pc 00000000000c1e40  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+208) (BuildId: 037ccd4f6c32456866be69c5a0a56591)
  native: #06 pc 0000000000054b50  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: 037ccd4f6c32456866be69c5a0a56591)
  (no managed stack frames)
...
----- end 17376 -----

如上截图中,有三个线程,一个是 Signal Catcher 线程,一个是 main 线程,一个是 Jit thread pool worker thread 0 ,他们的线程状态分别是 Runnableblockednative 状态。
而在 Java 中,线程状态有6种,如下所示:

  • NEW - 创建状态:当我们new一个Thread的时候,线程就处于创建状态;
  • RUNNABLE - 就绪或运行状态:当我们调用线程的 start() 方法,线程就会进入该状态;

另外,还有两种情况也会使线程进入就绪状态:

  • 线程之前处于阻塞状态,如果阻塞解除了,也会进入就绪状态
  • 线程之前处于运行状态,如果执行了 Thread.yield() 方法,则线程会进入就绪状态
  • BLOCKED - 阻塞状态:该状态下,线程正在阻塞等待某个锁。
  • WATING - 等待状态:当调用了以下某一个方法,线程就会处于等待状态:

Object.wait
Thread.join
LockSupport.park
处于等待状态的线程正在等待另一个线程执行特定操作,例如:

  • 在一个对象上调用了 Object.wait() 的线程正在等待另一个线程调用 Object.notify() 或 Object.notifyAll() 。
  • 已调用 Thread.join() 的线程正在等待指定线程终止。
  • TIMED_WAITING - 定时等待状态:指定等待时间的等待状态,当调用以下具有指定正等待时间的方法之一,线程就会处于定时等待状态:

Thread.sleep(long millis)
Object.wait(long timeout)
Thread.join(long millis)
LockSupport.parkNanos(long nanos)
LockSupport .parkUntil(long deadline)

  • TERMINATED - 终止状态:终止状态,线程已完成执行就会进入此状态。

那么,上述日志中的 native 状态是什么呢?
其实该状态是 cpp 代码中定义的线程状态,他跟 java 定义的线程状态关系如下:

java thread 状态 cpp thread状态 说明
TERMINATED ZOMBIE 线程死亡,终止运行
RUNNABLE RUNNING/RUNNABLE 线程可运行或正在运行
TIMED_WAITING TIMED_WAIT 执行了带有超时参数的wait, sleep或join函数
BLOCKED MONITOR 线程阻塞,等待获取对象锁
WAITING WAIT 执行了无超时参数的wait函数
NEW INITIALIZING 新建,正在初始化,为其分配资源
NEW STARTING 新建,正在启动
RUNNABLE NATIVE 正在执行JNI本地函数
WAITING VMWAIT 正在等待VM资源
RUNNABLE SUSPENDED 线程暂停,通常是由于GC或debug被暂停
UNKNOWN 未知状态

由上可知,native 状态对应的 java 线程状态是 runnable 状态。
堆栈信息是我们分析 ANR 的第一个重要的信息,一般来说:

  • 主线程处于 BLOCK / WAITING / TIMEWAITING 状态,基本上是函数阻塞导致的 anr
  • 若主线程无异常,则应该排查 CPU 负载和内存环境等其他因素

另外,在 anr 日志中,还有一些常见参数,他们的含义如下:

参数 含义
main main标识是主线程,如果是线程,那么命名成“Thread-X”的格式,x表示线程id,逐步递增。
prio 线程优先级,默认是5
tid tid不是线程的id,是线程唯一标识ID
group 是线程组名称
sCount 该线程被挂起的次数
dsCount 是线程被调试器挂起的次数
obj 对象地址
self 该线程Native的地址
sysTid 是线程号(主线程的线程号和进程号相同)
nice 是线程的调度优先级
sched 分别标志了线程的调度策略和优先级
cgrp 调度归属组
handle 线程处理函数的地址
state 是调度状态
schedstat 从 /proc/[pid]/task/[tid]/schedstat读出,三个值分别表示线程在cpu上执行的时间、线程的等待时间和线程执行的时间片长度,不支持这项信息的三个值都是0;
utm 是线程用户态下使用的时间值(单位是jiffies)
stm 是内核态下的调度时间值
core 是最后执行这个线程的cpu核的序号

三、分析

1.通过在 events_log 中检索 am_anr 关键字,就可以找到发生ANR的进程,譬如以下日志:

10-16 00:48:27 820 907 I am_anr: [0,29533,com.android.systemui,1082670605,Broadcast of Intent { act=android.intent.action.TIME_TICK flg=0x50000114 (has extras) }]

表示在 10-16 00:48:27 这个时刻,PID29533 进程发生了 ANR,进程名是 com.android.systemui
接下来可以在 sys_log 检索 ANR in 关键字,找到发生 ANR 前后的 CPU 使用情况:

10-16 00:50:10 820 907 E ActivityManager: ANR in com.android.systemui, time=130090695
10-16 00:50:10 820 907 E ActivityManager: Reason: Broadcast of Intent { act=android.intent.action.TIME_TICK flg=0x50000114 (has extras) }
10-16 00:50:10 820 907 E ActivityManager: Load: 30.4 / 22.34 / 19.94
10-16 00:50:10 820 907 E ActivityManager: Android time :[2015-10-16 00:50:05.76] [130191,266]
10-16 00:50:10 820 907 E ActivityManager: CPU usage from 6753ms to -4ms ago:
10-16 00:50:10 820 907 E ActivityManager:   47% 320/netd: 3.1% user + 44% kernel / faults: 14886 minor 3 major
10-16 00:50:10 820 907 E ActivityManager:   15% 10007/com.sohu.sohuvideo: 2.8% user + 12% kernel / faults: 1144 minor
10-16 00:50:10 820 907 E ActivityManager:   13% 10654/hif_thread: 0% user + 13% kernel
10-16 00:50:10 820 907 E ActivityManager:   11% 175/mmcqd/0: 0% user + 11% kernel
10-16 00:50:10 820 907 E ActivityManager:   5.1% 12165/app_process: 1.6% user + 3.5% kernel / faults: 9703 minor 540 major
10-16 00:50:10 820 907 E ActivityManager:   3.3% 29533/com.android.systemui: 2.6% user + 0.7% kernel / faults: 8402 minor 343 major
10-16 00:50:10 820 907 E ActivityManager:   3.2% 820/system_server: 0.8% user + 2.3% kernel / faults: 5120 minor 523 major
10-16 00:50:10 820 907 E ActivityManager:   2.5% 11817/com.netease.pomelo.push.l.messageservice_V2: 0.7% user + 1.7% kernel / faults: 7728 minor 687 major
10-16 00:50:10 820 907 E ActivityManager:   1.6% 11887/com.android.email: 0.5% user + 1% kernel / faults: 6259 minor 587 major
10-16 00:50:10 820 907 E ActivityManager:   1.4% 11854/com.android.settings: 0.7% user + 0.7% kernel / faults: 5404 minor 471 major
10-16 00:50:10 820 907 E ActivityManager:   1.4% 11869/android.process.acore: 0.7% user + 0.7% kernel / faults: 6131 minor 561 major
10-16 00:50:10 820 907 E ActivityManager:   1.3% 11860/com.tencent.mobileqq: 0.1% user + 1.1% kernel / faults: 5542 minor 470 major
...
10-16 00:50:10 820 907 E ActivityManager:  +0% 12832/cat: 0% user + 0% kernel
10-16 00:50:10 820 907 E ActivityManager:  +0% 13211/zygote64: 0% user + 0% kernel
10-16 00:50:10 820 907 E ActivityManager: 87% TOTAL: 3% user + 18% kernel + 64% iowait + 0.5% softirq

这一段日志它包含的信息量非常多:

  • 发生 ANR 的时间:events_log 中,ANR 的时间是 00:48:27,因为 AMS.appNotResponding() 首先会打印 events_log,然后再打印 syst_log, 所以,在 syst_log 中,找到ANR的时间是 00:50:10。可以从这个时间点之前的日志中,还原ANR出现时系统的运行状态。
  • 打印ANR日志的进程:ANR日志都是在 system_server 进程的AMS线程打印的,在events_log和sys_log中,都能看到 820 和 907, 所以system_server的PID是 802,AMS 线程的 TID 是 907。ANR的监测机制实现在 AMS线程,分析一些受系统影响的ANR,需要知道system_server进程的运行状态。
  • 发生ANR的进程:ANR in关键字就表明了当前ANR的进程是com.android.system.ui,通过events_log,知道进程的PID是 29533。
  • CPU使用统计时间段:CPU usage from XX to XX ago关键字表明了这是在ANR发生之前一段时间内的CPU统计。 类似的还有CPU usage from XX to XX after关键字,表明是ANR发生之后一段时间内的CPU统计。
  • 发生ANR的原因:Reason关键字表明了当前发生ANR的原因是,处理TIME_TICK广播消息超时。 隐含的意思是TIME_TICK是一个串行广播消息,在 29533 的主线程中,执行BroadcastReceiver.onReceive()方法已经超过10秒。(也有可能时其他原因,导致systemui进程分配不到CPU时间,从而主线程处理广播消息超时,发生了ANR。)

2.Blocked——ANR

Blocked关键字,在 ANR 日志里可以直接搜索 Blocked,看个例子:

"main" prio=5 tid=1 Blocked
  | group="main" sCount=1 dsCount=0 obj=0x75bd5818 self=0x7f8549a000
  | sysTid=29533 nice=0 cgrp=bg_non_interactive sched=0/0 handle=0x7f894bbe58
  | state=S schedstat=( 289080040422 93461978317 904874 ) utm=20599 stm=8309 core=0 HZ=100
  | stack=0x7fdffda000-0x7fdffdc000 stackSize=8MB
  | held mutexes=
  at com.mediatek.anrappmanager.MessageLogger.println(SourceFile:77)
  - waiting to lock <0x26b337a3> (a com.mediatek.anrappmanager.MessageLogger) held by thread 49
  at android.os.Looper.loop(Looper.java:195)
  at android.app.ActivityThread.main(ActivityThread.java:5718)
  at java.lang.reflect.Method.invoke!(Native method)
  at java.lang.reflect.Method.invoke(Method.java:372)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:975)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:770)

可以发现主线程 Blocked,并且这里有一行:

- waiting to lock <0x26b337a3> (a com.mediatek.anrappmanager.MessageLogger) held by thread 49

其含义就是,主线程正在被 block, 其正在等待 线程49 释放锁,最终因此导致出现了 ANR。
可以接着搜关键字 tid=49,如果简单的话一般会是:

"xxxThread" prio=5 tid=49 Sleeping

基本也可以定位到问题。

3.Slepping——ANR

Slepping关键字,在 ANR 日志里可以直接搜索 Slepping,看个例子:
MainActivity 代码如下:

class MainActivity : AppCompatActivity() {   
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
    /**
     * 点击睡眠 10s
     */
    fun clickToSleep(view: View) {
        Thread.sleep(10_000)
    }
}

当点击按钮睡眠 10s 后,我们左滑或者点击返回键退出 MainActivity(由于主线程正在睡眠,所以此时是无法退出成功的),等待一段时间,系统将会弹出 ANR 弹窗。

"main" prio=5 tid=1 Sleeping
  | group="main" sCount=1 dsCount=0 flags=1 obj=0x72e0ee78 self=0x79aafbcc00
  | sysTid=16356 nice=-10 cgrp=default sched=0/0 handle=0x79ac524ed0
  | state=S schedstat=( 1075827038 33414740 291 ) utm=93 stm=14 core=2 HZ=100
  | stack=0x7fe35ed000-0x7fe35ef000 stackSize=8192KB
  | held mutexes=
  at java.lang.Thread.sleep(Native method)
  - sleeping on <0x04fbafa5> (a java.lang.Object)
  at java.lang.Thread.sleep(Thread.java:440)
  - locked <0x04fbafa5> (a java.lang.Object)
  at java.lang.Thread.sleep(Thread.java:356)
  at com.example.demoproject.view.MainActivity.clickToSleep(MainActivity.kt:57)
  at java.lang.reflect.Method.invoke(Native method)
  at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:441)
  at android.view.View.performClick(View.java:7259)
  at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1194)
  at android.view.View.performClickInternal(View.java:7236)
  at android.view.View.access$3600(View.java:801)
  at android.view.View$PerformClick.run(View.java:27896)
  at android.os.Handler.handleCallback(Handler.java:883)
  at android.os.Handler.dispatchMessage(Handler.java:100)
  at android.os.Looper.loop(Looper.java:214)
  at android.app.ActivityThread.main(ActivityThread.java:7397)
  at java.lang.reflect.Method.invoke(Native method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:935)

从堆栈信息中也很容易发现,在执行到 MainActivity.clickToSleep 方法时,线程进行了睡眠,最终导致 ANR。

4.耗时或死循环方法

例子如下:

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
   
    fun click(view: View) {
        doSomething()
    }
    private fun doSomething() {
        // 注意这里死循环
        while (true) {
            Log.i("testLog", "doSomething.. 当前线程名称=${Thread.currentThread().name} 线程id=${Thread.currentThread().id}")
        }
    }
}

当我们点击按钮时,会在主线程通过一个死循环不断打印 log,因此 doSomething() 方法我们可以认为是一个耗时方法,点击按钮后,我们左滑或者点击返回键退出 MainActivity(由于主线程正在忙碌中,所以此时是无法退出成功的),等待一段时间,系统将会弹出 ANR 弹窗。
ANR日志如下:

----- pid 13231 at 2022-06-17 14:23:41 -----
Cmd line: com.example.demoproject
...
"main" prio=5 tid=1 Runnable
  | group="main" sCount=0 dsCount=0 flags=0 obj=0x72b20e78 self=0x77fe5a6c00
  | sysTid=13231 nice=-10 cgrp=default sched=0/0 handle=0x77ffb0eed0
  | state=R schedstat=( 31694533124 58819622 723 ) utm=1310 stm=1859 core=5 HZ=100
  | stack=0x7fdc2b7000-0x7fdc2b9000 stackSize=8192KB
  | held mutexes= "mutator lock"(shared held)
  native: #00 pc 00000000004108e8  /apex/com.android.runtime/lib64/libart.so (art::DumpNativeStack(std::__1::basic_ostream<char, std::__1::char_traits<char>>&, int, BacktraceMap*, char const*, art::ArtMethod*, void*, bool)+140)
  native: #01 pc 00000000004f8040  /apex/com.android.runtime/lib64/libart.so (art::Thread::DumpStack(std::__1::basic_ostream<char, std::__1::char_traits<char>>&, bool, BacktraceMap*, bool) const+512)
  native: #02 pc 000000000051297c  /apex/com.android.runtime/lib64/libart.so (art::DumpCheckpoint::Run(art::Thread*)+828)
  native: #03 pc 00000000004f8d4c  /apex/com.android.runtime/lib64/libart.so (art::Thread::RunCheckpointFunction()+176)
  native: #04 pc 00000000003713fc  /apex/com.android.runtime/lib64/libart.so (art::(anonymous namespace)::CheckJNI::ReleaseStringCharsInternal(char const*, _JNIEnv*, _jstring*, void const*, bool, bool)+1356)
  native: #05 pc 00000000001507cc  /system/lib64/libandroid_runtime.so (android::android_util_Log_println_native(_JNIEnv*, _jobject*, int, int, _jstring*, _jstring*)+232)
  at android.util.Log.println_native(Native method)
  at android.util.Log.i(Log.java:176)
  at com.example.demoproject.view.MainActivity.doSomething(MainActivity.kt:52)
  at com.example.demoproject.view.MainActivity.click2(MainActivity.kt:36)
  at java.lang.reflect.Method.invoke(Native method)
  at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:441)
  at android.view.View.performClick(View.java:7259)
  at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1194)
  at android.view.View.performClickInternal(View.java:7236)
  at android.view.View.access$3600(View.java:801)
  at android.view.View$PerformClick.run(View.java:27896)
  at android.os.Handler.handleCallback(Handler.java:883)
  at android.os.Handler.dispatchMessage(Handler.java:100)
  at android.os.Looper.loop(Looper.java:214)
  at android.app.ActivityThread.main(ActivityThread.java:7397)
  at java.lang.reflect.Method.invoke(Native method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:935)
...
----- end 16808 -----

发现主线程正处于 Runnable 状态,并不是处于空闲状态,堆栈信息中有一行关键日志:

at com.example.demoproject.view.MainActivity.doSomething(MainActivity.kt:52)

各关键字:am_anr、ANR in、Reason、Blocked、Slepping。

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

推荐阅读更多精彩内容