记录一次ANR的分析过程

Android开发中难免碰到ANR问题,但是网上关于ANR的文章并不多,那我就写一篇最近工作中碰到ANR的分析过程。

分析过程

  • 先查一下网上关于ANR方面的文章,找到的大部分都是说不要主线程执行耗时操作,但是我本来就在子线程里执行的下载操作的。怎么会产生ANR?
  • 接着去分析 /data/anr/traces.txt, 好家伙data文件夹不是要root权限 才能访问吗?怎么办不是要我root吧,然后我又去查了资料发现可以用下面的命令导出traces文件

adb shell cat /data/anr/traces.txt > e:\anr.txt

  • 打开anr.txt 有1000多行看着都晕,没办法慢慢看吧,看到SharedPreferences想到了我不是在下载的时候存了下载的进度了,猜想应该是它出的问题
 | group="main" sCount=1 dsCount=0 obj=0x12dbdac0 self=0xb4256800

  | sysTid=4302 nice=0 cgrp=default sched=0/0 handle=0x9d207000

  | state=S schedstat=( 11836166912 2318327808 16610 ) utm=552 stm=631 core=1 HZ=100

  | stack=0x9c7f2000-0x9c7f4000 stackSize=1036KB

  | held mutexes=

  at libcore.io.Posix.fsync(Native method)

  at libcore.io.BlockGuardOs.fsync(BlockGuardOs.java:143)

  at java.io.FileDescriptor.sync(FileDescriptor.java:74)

  at android.os.FileUtils.sync(FileUtils.java:152)

  at android.app.SharedPreferencesImpl.writeToFile(SharedPreferencesImpl.java:598)

  at android.app.SharedPreferencesImpl.access$800(SharedPreferencesImpl.java:51)

  at android.app.SharedPreferencesImpl$2.run(SharedPreferencesImpl.java:512)

  - locked <@addr=0x131d6bf0> (a java.lang.Object)

  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)

  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)

  at java.lang.Thread.run(Thread.java:818)
  
  • 然后去代码里查了一下写的apply 方法,再去网上查了一下apply、和commit的区别
    SharedPreferencesImpl源码分析
    原来的apply方法是异步执行的,因为下载很快 有进行一次写入操作,在异步写入时导致死锁。
    commit是同步的阻塞的。

  • 那就把apply改成commit试一下,果然ok了。

TIP

在分析traces.txt首先搜索自己项目包名的堆栈,这样能很快定位问题,如果没有那就要一步一步的看,在关联自己的代码进行联想。应该能解决ANR问题。

    原文作者:qi丶
    原文地址: https://www.jianshu.com/p/d77bf98bd02a
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞