美文网首页
Android10上”org.apache.commons.co

Android10上”org.apache.commons.co

作者: tinyvampirepudg | 来源:发表于2020-08-06 11:25 被阅读0次

    在一次版本迭代后,突然在部分机型上爆出了一些崩溃,查看崩溃原因,原因内容是java.lang.NoClassDefFoundError:Failed resolution of: Lcom/apache/commons/desc/binary/Hex,具体如下图:

    image

    比较蛋疼的是在这次版本迭代后才出现这个问题,而且是高版本手机有问题,10.0的测试机有问题,6.0的测试却没问题。

    问题定位及解决

    基于上述不同机型的表现,用代码验证下,org.apache.commons.codec.binary.Hex这个类的加载情况,验证代码如下:

    try {
        Class.forName("org.apache.commons.codec.binary.Hex");
        Log.e("HexTest","success");
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
        Log.e("HexTest","failed");
    }
    

    经过验证,在10.0的手机上输出的是falied,6.0的手机上输出的是success

    org.apache.commons.codec.binary.Hex这个类到底是干嘛的?是哪个包下的呢?
    全局搜索项目代码,没发现org.apache.commons.codec.binary.Hex,这就表示这个类不是我们项目自己添加的依赖。

    为了先解决问题,我就找到了相应的jar包,具体位于Apache Commons Codec,通过下面的方式给项目添加了依赖:

        compile group: 'commons-codec', name: 'commons-codec', version: '1.14'
    

    问题暂时解决了。

    问题原因分析

    接下来我们来分析下出现这个问题的原因,问题的核心在于6.0的手机上是可以加载到这个类的,10.0的手机加载不到,初步猜测是手机系统内置了这个类,高版本的手机默认把这个类给hide了。

    后来经过详细的排查本次迭代的代码,发现了一处可能的原因,就是编译版本compileSdkVersion27升级到了28,然后把compileSdkVersion回退到27,这个问题果然没了。

    api 28对应的是Android 9,具体对应关系请看Android version history

    emmmmmm,现在的问题是compileSdkVersion从27到28,跟这个apache的包hide起来有什么关系?

    突然想起来Android6.0(也就是api 23)中移除了对Apache HTTP客户端的支持,这个也是apache包,他们之间是不是有什么关系呢?我们看下官网,它的解释是这样的:

    Apache HTTP 客户端弃用
    在 Android 6.0 中,我们移除了对 Apache HTTP 客户端的支持。从 Android 9 开始,该内容库已从 bootclasspath 中移除,且默认情况下应用无法使用它。
    

    我们找一个org.apache.http.legacy的jar包分析一下,具体如下:

    image

    org.apache.http.legacy包下有我们想要的org.apache.commons.codec.binary.Hex类,那么我们可以参照官网提供的在高版本使用org.apache.http.legacy建议即可,具体参考Apache HTTP 客户端弃用

    我们只需要在AndroidManifest.xml中添加以下内容即可:

    <uses-library
        android:name="org.apache.http.legacy"
        android:required="false" />
    

    当然了,我们还可以用另一种方式,在模块的build.gradle中添加如下代码即可:

    android { 
        useLibrary ‘org.apache.http.legacy'
    }
    

    需要说明的是,我们每个版本的Android sdk中其实都是有org.apache.http.legacy的jar包的,具体位于sdk/platforms/android-xx/options/路径下,如下图:

    image

    至此,出现问题的原因搞明白了,我们平时能引用到org.apache.commons.codec.binary.Hex类或者org.apache.commons.codec.binary.Base64这些类,是因为Android自带的org.apache.http.legacyjar包中包含了它们。如果你项目的compileSdkVersionapi 28及以上,那你就需要注意下这个问题了。

    参考

    Apache HTTP 客户端弃用

    相关文章

      网友评论

          本文标题:Android10上”org.apache.commons.co

          本文链接:https://www.haomeiwen.com/subject/pmjzrktx.html