本文已参与「新人创作礼」活动,一起开启掘金创作之路。android ANR实战(利用android studio profiler定位ANR)

380 阅读1分钟

 案例:个股详情界面失去焦点后发生ANR,必现。

在发生ANR生启用android stuiod profiler, 调用CPU Sample Java Methods  开启cpu 监测一段时间。

结果如下:

​编辑

由上图可以看到,main 线程中程序一直在执行

查看主线程方法调用情况 

​编辑

​编辑

​编辑

​编辑

从上面两个图可以看出来, 主线程 markState() 方法执行占用CPU高达99.60%,耗时长,则表示一定是此处造成的ANR。

从调用顺序可以看出,是由于StockDataInfoActivity.onStop()方法执行后造成的,这与造成的ANR现象一致,是个股详情界面失去焦点时发生ANR.

markState()方法是Fragment的源码,启动debug模式, 最终发现是该方法循环递归造成的。

原因:项目tragetSdkVersion为28, fragmnet的V4包是28.0.0,在个股详情界面SherlockFragmentActivity 所加载的StockDataInfoFragment所继承的LazyLoadFragment中,在onStop onResume onPasue等生命周期方法中调用了getLifecycler().handleLifecyclerEvent()方法。

@Override
public void onStop() {
    super.onStop();
    handleLifecycleEvent(Lifecycle.Event.ON_STOP);
}
.......


private void handleLifecycleEvent(Lifecycle.Event event) {
    if (mLifecycleRegistry != null) {
        mLifecycleRegistry.handleLifecycleEvent(event);
    }
}

在26.0.0版本及之前的V4包中的fragment 没有getLifecycle()方法,如果需要使用LifecycleRegistery,则需要自己重写生命周期方法并发送相应的事件;而在26.0.1及以后,源码已经处理了,此时如果在业务代码中,再去发送这些事件,就会导致V4 fragment源码中处理生命周期事件时发生递归,造成死循环。

解决方法:删除 mLifecycleRegistry.handleLifecycleEvent(event) 相关代码即可。

希望对大家有用!!!

\