Android ANR,看完不慌
隔壁部门做了一个评价器,就是一个jsp页面在安卓设备上一直运行,安卓原生部分的很简单,就是通过webview加载,打了个apk。最近用户反馈说在运行一段时间后,有时4-5个小时,有时10几个小时,再次点击页面就会出现程序无响应的情况。于是找到我这边给测试解决,说真的,我比较慌。
a.自己提出了几个可能的问题:
1.设备的问题(因为集中采购的是一些奇奇怪怪的设备)。
不过从设备信息看,除了low一些,看不出啥问题。
2.webview的问题,或相关settings没有配置。
看一一下,他们打的包是用原生的webview,我比较习惯用腾讯x5内核的,就是这个
com.tencent.smtt.sdk.WebView
webView = new WebView(getApplicationContext());
webView.setLayoutParams(new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
relativeLayout.addView(webView);
WebSettings的相关配置也是添加的
WebSettings s = webView.getSettings();
s.setJavaScriptEnabled(true);
s.setJavaScriptCanOpenWindowsAutomatically(true);
@SuppressLint("SdCardPath") String path = "/data/data/" + context.getPackageName() + "/databases/";
s.setAppCachePath(path);
s.setAppCacheEnabled(true);
s.setCacheMode(WebSettings.LOAD_NO_CACHE);
s.setSaveFormData(true);
s.setDomStorageEnabled(true);
tWebChromeClient 及WebViewClient相关也是设置了的,看起来也没啥问题。
3.页面的问题。
页面不是我写的,没证据不能讲。
b.自己提出了几个可能的问题
假设被推翻,出问题的时间也没法确定,看来捷径是走不通了,只能从抓日志下手了,这里用了友盟统计的sdk去帮助完成这一步,等待两天之后,错误日志收获满满,还是比较兴奋的。
待俺赶上前去,选取一条仔细观瞧,不由得一身冷汗,尴尬了,看不懂。
莫慌,看不不要紧,根据指导原则猜猜也是有用的。
ANR 顾名思义Application Not Response ,就是程序无响应,应用跑着跑着Duang的卡住了,无法响应用户的操作如触摸事件等等
触发原因和分类,也就是指导原则
触发ANR的原因
- 应用进程自身引起
例如:
1.主线程阻塞、挂起、死循环
2.应用进程的其他线程的CPU占用率高,使得主线程无法抢占到CPU时间片 - 其他进程间接引起(误伤)
例如:
1.当前应用进程进行进程间通信请求其他进程,其他进程的操作长时间没有反馈
2.其他进程的CPU占用率极高,使得当前应用进程无法抢占到CPU时间片
ANR的分类:
- 应用在5秒内未响应用户的输入事件,如按键或触摸事件
- BroadcastReceiver未在10秒内完成相关的处理
- Service的各个生命周期函数时20秒内没有执行完毕
接下来试着读读日志
anr traces:
generate begin time: 2020-09-10 08:40:39
[DEBUG] dump art internal: 111
[DEBUG] VMExt: 0xb4c7c000, i: 64, str: 3
[DEBUG] runtime trace: 33,20,/data/anr/traces.txt
[DEBUG] aborting: 0xb4bfde3c, 0
[DEBUG] Dump: 0x0, State: 0xb4aed931, JavaStack: 0xb4ae878d
[DEBUG] Thread spec key: 0xb4bff7fc
[DEBUG] current: 0xb4cb6500, pid: 6495
[DEBUG] List: 0xb4c6a800
[DEBUG] Each: 0xb4af3b09
[DEBUG] err: 0xb6d4ee44
[DEBUG] begin each
[DEBUG] dumping 0xb4cb6500 ...
main prio=7 tid=1 Native
| group= sCount=0 dsCount=0 obj=0x74bcc000 self=0xb4cb6500
| sysTid=4068 nice=-4 cgrp=default sched=0/0 handle=0xb6f0cb34
| state=? schedstat=( 0 0 0 ) utm=0 stm=0 core=0 HZ=100
| stack=0xbe71d000-0xbe71f000 stackSize=8MB
| held mutexes=
at android.view.ThreadedRenderer.nSyncAndDrawFrame(Native method)
at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:341)
at android.view.ViewRootImpl.draw(ViewRootImpl.java:2620)
at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2439)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2072)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1112)
[DEBUG] runtime trace: 33,20,/data/anr/traces.txt
这句告诉我们anr日志保存路径(没卵用)
main prio=7 tid=1 Native
main 表示主线程 prio线程优先级 tid不是线程的id,它是一个在Java虚拟机中用来实现线程锁的变量,随着线程的增减,这个变量的值是可能被复用的. Native不必多说。
tid对应值解释说明
后面一行
group= sCount=0 dsCount=0 obj=0x74bcc000 self=0xb4cb6500
group是线程组名称。sCount是此线程被挂起的次数,dsCount是线程被调试器挂起的次数,当一个进程被调试后,sCount会重置为0,调试完毕后sCount会根据是否被正常挂起增长,但是dsCount不会被重置为0,所以dsCount也可以用来判断这个线程是否被调试过。obj表示这个线程的Java对象的地址,self表示这个线程本身的地址。
此后是线程的调度信息
sysTid=4068 nice=-4 cgrp=default sched=0/0 handle=0xb6f0cb34
sysTid是Linux下的内核线程id,nice是线程的调度优先级,sched分别标志了线程的调度策略和优先级,cgrp是调度属组,handle是线程的处理函数地址。
然后是线程当前上下文信息
state=S schedstat=( 303590361913 618664734427 651535 ) utm=19466 stm=10893 core=0
state是调度状态;schedstat从 /proc/[pid]/task/[tid]/schedstat读出,三个值分别表示线程在cpu上执行的时间、线程的等待时间和线程执行的时间片长度,有的android内核版本不支持这项信息,得到的三个值都是0;utm是线程用户态下使用的时间值(单位是jiffies);stm是内核态下的调度时间值;core是最后执行这个线程的cpu核的序号。
最后就是这个线程的调用栈信息。
stack=0xbe71d000-0xbe71f000 stackSize=8MB
看了日志文件,对于如何找出ANR的真正原因,还是一件难事,其实说难不难,文本冗长我们没必要弄懂每一行的意思,一般的,如果是我们的应用造成的anr,至少能够在这个文件里看到包名com.xxx.xx的表述,结合上下文分析应该不难,但我这个没找到。
除了找应用信息,查找wating ,anr等关键字,因为anr的情况一般是让主线程做了很多耗时的操作,我这个是应用长驻的,放在柜台员前让办事用户再办完事情进行评价的,很简答的功能,原生并没有耗时操作,jsp页面问了问写的人员也没有做耗时操作,这就很奇怪。
苦苦阅读这个anr日志时,事情出现了转机,外派员反馈另一个地区的设备是来自不同厂商的,出现问题后厂商过来给设备进行过处理,目前那一批设备是好的(为啥不早说),于是联系那边询问,做了什么骚操作,发来了一个文件夹:
图片.png
简单看了看,主要是给更新了WebViewGoogle_arm32.apk,手机上是见过这东西的,开发者选项下查看`webView实现'就能够看到,小米华为都有,然而我手里这台设备在设置里搜寻一圈都没有(什么鬼设备)
果断把这玩意给打上去,之后在 “设置-->应用-->Android System WebView” 看到了这个东西,不知道是否会生效。
继续打开评价器,静置一个晚上,看明日会不会有错误。就写到这里。