在现有app中搜索界面增加了一个功能后,反复 *** 作,大概率出现黑屏,应用卡死。
到处anr日志,但是仍然没有看到什么有用的信息。
和修改前的功能进行对比,最终找到了问题点。
我需要显示一个悬浮d框,这个还需要定时关闭;
如果新来消息,还需要复用这个d框,就需要取消之前的定时关闭。
实现定时关闭:
viewpostDelayed({hideView()}, 10000)
清除之前的定时:
viewhandlerremoveCallbacksAndMessages(null)
问题点就出在上面removeCallbacksAndMessages。
这个是跟场景有关系的,因为我是在搜索界面,当点击搜索后,触发上面显示d框的 *** 作,还会触发关闭软键盘。
推测removeCallbacksAndMessages会清空所有消息,同时又有其他消息需要加入其中,中间出现了死锁。
只是推测,未作完整深究。
Java层的crash一般可以在日志中看到发生问题时的调用栈,比较容易定位问题。
Native层的crash一般只能看到发生问题时相关的地址和简单的原因,需要结合native的调用栈和日志中的上下文进行分析。
Linux Signal:对应Java层的Exception。
Linux Signal 列表
常见Signal:
ANR(Application Not Responding)是指应用程序无响应,Android系统规定一些事件必须在一定时间范围内完成,如果超过预定时间未能得到有效响应或者响应时间过长,都会造成ANR。
ANR由消息处理机制保证,Android在系统层实现了一套精密的机制来检测ANR,核心原理是消息调度和超时处理。
1分析ANR日志
2分析是否native层crash导致ANR
3分析是否业务逻辑缺陷导致ANR
xcrash 是爱奇艺在2019年4月开源在GitHub上的稳定性日志收集框架,它能为android收集java crash、native crash、anr日志。不需要root权限和系统权限。支持 Android 40 - 10(API level 14 - 29),支持 armeabi,armeabi-v7a,arm64-v8a,x86 和 x86_64。
xcrash作为门面模式的入口,client调用通过配置InitParameter来进行初始化。Xcrash分别关联三种类型Handler来处理对应的奔溃监听和日志收集,通过FileManager和TombstoneManager对奔溃日志进行tombstone文件管理。client调用TombstoneParser来解析本地生成的对应tombstone文件,获取数据。
Java层的崩溃可以直接交给JVM的崩溃捕获机制去处理。这个非常简单,不赘述。
如果有java crash发生,会回调uncaughtException,执行handleException收集相关log信息
Crashjava
NativeHandlerjava
NativeHandler在Xcrash init时会执行initialize方法进行初始化,初始化过程首先通过SystemloadLibrary("xcrash”)注册native函数,其次就是调用nativeInit。
执行SystemloadLibrary("xcrash”),JNI_OnLoad会被回调,这里是动态注册玩法。
xc_jnic
数组0元素对应:
java层调用nativeInit,native xc_jni_init会被调用。
接着看nativeInit逻辑
xc_jnic
先看xc_crash_init
1)设置callback:
xc_crash_init_callback最终回调的是NativeHandler的crashCallback
2)信号注册:
注册的是指针函数:xc_crash_signal_handler,追过去看看:
进入xc_crash_exec_dumper指针函数,看看进程dump *** 作:
这个部分是做各种数据的dump。简单找下main方法:
xcd_corec
不细看了,整个过程先是挂起crash进程的所以线程,然后收集相关log,最后resume所有线程。
xc_trace_init部分不分析了,与xc_jni_init分析方法一致。这里也就简单分析了个大脉络。
Native崩溃处理步骤总结:
同样在Xcrash init时初始化
Crashjava
这里有个限制,是sdk <21的版本才抓取。
AnrHandlerjava
高版本系统已经没有读取/data/anr/的权限了,因此FileObserver监听/data/anr/的方案只能支持<21的版本,而目前xcrash对>21的版本无法获取anr日志。
然后看看handleAnr收集了哪些数据:
这里重点关注checkProcessAnrState,它是AMS对外暴露的api,从AMS的mLruProcesses中过滤出crash和anr异常的进程,返回对应的错误信息。补充cause reason部分,也就是ANR in。
那么>21版本的anr如何抓取?
//init native crash handler / ANR handler (API level >= 21)
int r = ErrnoOK;
if (paramsenableNativeCrashHandler || (paramsenableAnrHandler && BuildVERSIONSDK_INT >= 21)) {
r = NativeHandlergetInstance()initialize();
}
是通过nativeHandler来抓的。也就是前面提到的
它是native 注册 SIGNAL_QUIT 信号,ANR发生时接收回调去收集ANR信息。
这里xc_trace_notifier是一个eventfd ,在handler接收信号回调时被写
然后xc_trace_dumper线程会解除阻塞状态开始执行dump任务。
本篇文章简单分析了下xcrash257源码,结合之前 java crash处理分析 和 native crash 处理分析,对app收集奔溃日志的整个过程有了个全面了解。
以上就是关于安卓App出现黑屏ANR问题-实战记录全部的内容,包括:安卓App出现黑屏ANR问题-实战记录、稳定性 -- Crash & ANR、Xcrash V2.5.7框架解析等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)