大家新年好,这个文章聊下kotlin的mapping文件的定位,以具体一个线上崩溃为例
Caused by: java.lang.IndexOutOfBoundsException: toIndex = 10
at java.util.AbstractList.subListRangeCheck(AbstractList.java:507)
at java.util.ArrayList$SubList.subList(ArrayList.java:1238)
at b.a.a.a.p.y1.i(SearchRecordFragment.kt:12)
at b.a.a.a.p.f0.run(lambda:6)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:264)
at android.app.ActivityThread.main(ActivityThread.java:8306)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:632)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1049)
通过上面的崩溃日志,可以发现具体崩溃的代码是这里
at java.util.ArrayList$SubList.subList(ArrayList.java:1238)
at b.a.a.a.p.y1.i(SearchRecordFragment.kt:12)
这里b.a.a.a.p.y1
代表某个类,最后的i
代表的是一个方法,或者变量,这里实际是一个方法,因为有前后调用堆栈,这里调用到sublist方法导致的崩溃,最后的kt:12
代表的是混淆后的行数是12行
接下来,我们打开mapping文件,搜索b.a.a.a.p.y1
这个字符串,结果如下
找到对应的类下的mapping信息,接下来就是找i
,可以发现这个类里面有很多i的声明,比如下面这几种,都不是我们要找的i
// 这个i是一个Lzay类型的变量
kotlin.Lazy lateSearchRecordAdapter$delegate -> i
// 前面的3:4的行数不对,我们要找的是12
3:4:void com.ygp.mro.app.search.adapter.SearchRecordAdapter.setShowExpandView(boolean):50:51 -> i
继续找,找到了最终匹配的位置,如下
11:11:java.util.List com.ygp.mro.app.search.adapter.SearchRecordAdapter.getData():22:22 -> i
11:11:void initListShowExpand():185 -> i
12:13:void initListShowExpand():185:186 -> i
14:14:void com.ygp.mro.app.search.adapter.SearchRecordAdapter.setData(java.util.List):0:0 -> i
14:14:void initListShowExpand():186 -> i
上面的中间那行,就是我们要的结果12:13:void initListShowExpand():185:186 -> i
,混淆后的12:13对应的真实的行数是185:186,所以实际崩溃的就是185行
看下对应的源码
源码这里也有调用到sublist方法,跟崩溃调用的方法一致,于是确定是这里导致的崩溃了
通过源码跟mapping,都可以发现,崩溃的方法是initListShowExpand
,那这个方法又是哪里调用的呢?我们通过查看,有两个地方调用到
具体崩溃的时候,是哪里调用的,再看下崩溃的log
at b.a.a.a.p.y1.i(SearchRecordFragment.kt:12)
at b.a.a.a.p.f0.run(lambda:6)
at android.os.Handler.handleCallback(Handler.java:938)
是这里的b.a.a.a.p.f0
的run方法,而run方法又是handler回调的,继续去mapping文件搜索b.a.a.a.p.f0
找到了很多run的调用,而方法后面有这个lambda:6
,我们找对应的6这个地方,找到了
6:6:void com.ygp.mro.app.search.SearchRecordFragment$initListener$2.onGlobalLayout$lambda-1(com.ygp.mro.app.search.SearchRecordFragment):151:151 -> run
6:6:void com.ygp.mro.app.search.SearchRecordFragment$initListener$2.lambda$EpImLmOa5i7W3KU8Q9jIBuQ78Gk(com.ygp.mro.app.search.SearchRecordFragment):0 -> run
6:6:void run():0 -> run
对应的是源码的151行,查看源码,找到了调用的代码了
所以结果是151行调用initListShowExpand
方法,然后在方法内部的185行发生了崩溃