安卓App出现黑屏ANR问题-实战记录

安卓App出现黑屏ANR问题-实战记录,第1张

在现有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框架解析等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/10066081.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-04
下一篇 2023-05-04

发表评论

登录后才能评论

评论列表(0条)

保存