Android踩坑记录-混淆踩坑之(java.lang.NoSuchMethodError: No interface method f()I in class...)

Android踩坑记录-混淆踩坑之java.lang.NoSuchMethodError: No interface method f()I in class Landroid/content/res/XmlResourceParser; or its super classes

    • 前言
    • 出现的问题
    • 出现问题的原因以及分析
    • 解决办法
    • 最后

前言

好像是第一次写公开博客,目的很简单,总结一下这个坑以后绝对不会再踩,真的耽搁了很多时间来爬出坑。顺便为了让遇到跟我一样问题的同僚们第一时间能搜到这个博客。
博主使用的是Android Studio IDE
好了废话不多说。

出现的问题

错误就是如下这个样子

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: xxx.xxx.xxx, PID: 6133
    java.lang.NoSuchMethodError: No interface method f()I in class Landroid/content/res/XmlResourceParser; or its super classes (declaration of 'android.content.res.XmlResourceParser' appears in /system/framework/framework.jar)
        at androidx.core.content.FileProvider.parsePathStrategy(FileProvider.java:618)
        at androidx.core.content.FileProvider.getPathStrategy(FileProvider.java:579)
        at androidx.core.content.FileProvider.attachInfo(FileProvider.java:392)
        at android.app.ActivityThread.installProvider(ActivityThread.java:6093)
        at android.app.ActivityThread.installContentProviders(ActivityThread.java:5572)

起初我也看懂,我也是小白,于是在百度上各大网站上寻找我想要的答案,不过大家异口同声说是导入了两个版本不同的包,有可能你也是这个问题,如果想排除这种可能,你可以前往其他博客看看。不过我遇到的不是这个问题哈哈

出现问题的原因以及分析

看错误日志其实可以看出一些东西,意思就是在这个Landroid/content/res/XmlResourceParser类或者它的父类android.content.res.XmlResourceParser没有这个f()方法,这个f()一般都是混淆后的函数名,一般在项目里没人会用这样的名字命名吧,主要是运行的时候也没报错,这是打包出来的Apk安装后启动就闪退,于是我尝试关闭混淆再打包一次,果然没有报错了。
因此定位到了是混淆的错误,那就好办了,把这个包keep一下不混淆不就行了吗。于是菜鸟的我又百度了一下混淆的规则。在项目目录的proguard-rules.pro文件下加入了下面的代码:

-keep class android.content.** {*;}
-keep public class * extends android.content.**
-keep interface android.content.** {*;}

意思就是不混淆Android.content.下的所有类和方法。
然而结果是完全没有用!仍然是同样的错误,说明那个
interface
还是被混淆了。

我们再回到它的错误日志,有时候我们得仔细看它的错误日志,日志说有可能在android.content.res.XmlResourceParser或者它的父类包里没有这个方法。
Android踩坑记录-混淆踩坑之(java.lang.NoSuchMethodError: No interface method f()I in class...)_第1张图片没有这个方法?这个方法指的是哪个方法,我们定位到FileProvider的618行
Android踩坑记录-混淆踩坑之(java.lang.NoSuchMethodError: No interface method f()I in class...)_第2张图片
可以看到为XmlResourceParser类型的是while中的in
Android踩坑记录-混淆踩坑之(java.lang.NoSuchMethodError: No interface method f()I in class...)_第3张图片
也就是说没有这个next()方法,它这不是在这儿吗?编译器憨憨吗,我们点进next()看看
Android踩坑记录-混淆踩坑之(java.lang.NoSuchMethodError: No interface method f()I in class...)_第4张图片
next()是
XmlPullParser
类中的方法,原来这个XmlResourceParser类仅仅只是实现了XmlPullParser类,那么应该是这个方法被混淆了才导致了这个错误。

解决办法

于是乎,在混淆规则中添加XmlPullParser类对应包的保持规则:

-keep class org.xmlpull.** {*;}
-keep public class * extends org.xmlpull.**
-keep interface org.xmlpull.** {*;}

问题解决,完美运行
好了就到这里,希望能够帮到你哦

最后

文章看起来话很多,不够直接,“博主直接给错误然后给解决办法就行了,说这么多干嘛”,然而我觉得更多的是学会分析问题,你才能真正解决问题,是解决一类问题,而不是解决一个问题,不然后面遇到类似的问题还是会手足无措。

你可能感兴趣的:(Android踩坑记录-混淆踩坑之(java.lang.NoSuchMethodError: No interface method f()I in class...))