• 【问题解决】Android JDK版本不匹配导致崩溃踩坑记录


    【问题解决】Android JDK版本不匹配导致崩溃踩坑记录

    前几天同事遇到一个非常诡异的报错,紧急处理后,趁着周末仔细研究了一下原因,觉得还挺有意思的,所以记录一下

    部分机型反馈崩溃问题

    问题背景:在一个SDK工程,前几天客户那边报了一个崩溃问题,并且在API 28以上的系统才会:
    No virtual method keySet()Ljava/util/concurrent/ConcurrentHashMap$KeySetView

    查看调用栈后发现调用到了ConcurrentHashMap#keySet ,顺着调用发现这是一个JDK1.8的API

    在这里插入图片描述
    这么看起来应该是JDK7 和JDK8的一个兼容问题,具体的问题需要继续往下看

    第一反应是是不是因为当前工程是JDK7的工程导致的?因为之前也在JDK7的工程上集成过JDK8的三方库,因为字节码不匹配导致崩溃,当时的解决方案有几种:

    1. 将工程和模块的JavaVersion设置为 Java7语言
    2. defalutConfig 里配置 jackOptions{ enable = true}
    3. 升级至Java8,可能遇到乱七八糟的问题可以通过一起升级gradle版本解决

    但是想想也不对,因为我是作为SDK的提供方,提供的应该也是JDK7的字节码,反编译后查看字节码也确实是JDK7的,虽然查看字节码确实有KeySetView,但是提供给JD8的工程用应该也不至于崩溃吧
    在这里插入图片描述

    谷歌回复与解决方案

    1. 首先当然要尽快解决客户反馈的问题,因为很快能够定位到问题,直接换种方式进行遍历/获取就可以了,接下来研究下为啥会出现这种情况
    2. 部分系统上是没有问题的,说明这个跟系统版本以及环境有关,如果是较老的系统缺少相关的API确实会导致崩溃
    3. 查询资料发现:谷歌回复已解决

    Android打包脱糖操作

    回想起APK的打包流程,最后打包成dex文件的时候好像是没看到有JDK版本的区别,并且JDK8的工程也是可以兼容老的机器的,这就想到了打包时的一个脱糖操作(对lambda表达式的处理也是如此),回顾一下相关的知识点:

    • android打包的脱糖处理

    在这里插入图片描述

    • JDK8语法支持表

    在这里插入图片描述

    • DX、D8、R8
    • DX:class文件转化为dex
    • D8:脱糖、class文件转换为dex
    • R8:整合了Proguard和D8 ,减少了一个编译步骤,同时保留了字节码优化能力

    对比与排查

    了解到上面的知识,随即仔细的看了下出SDK的分支,结果发现…
    在这里插入图片描述

    这居然是还是个java工程!!!那自然没有脱糖相关的操作了,再看下输出的jar
    在这里插入图片描述

    升级成android library 工程后打包的aar,输出产物正常!撒花

    在这里插入图片描述

    总结

    • 如果是java7的工程,需要引入java8的SDK,除了升级本地的工程的话,其实也可以去手动去修改别人的SDK(不建议)
    • 如果是发现提供出去的SDK存在包含JDK8的字节码的话,可以检查一下当前的编译环境是否使用了OpenJDK或者是否是android工程

    最后最后,如果觉得有帮助欢迎点个👍或关注~

  • 相关阅读:
    关于tcp发送成功但对端无法接收情况的思考
    如何在 Elasticsearch 中使用 Openai Embedding 进行语义搜索
    open62541开发:添加sqlite3 历史数据库
    mybatis-plus异常:dynamic-datasource can not find primary datasource
    java 工程管理系统源码+项目说明+功能描述+前后端分离 + 二次开发
    局域网下共享文件夹全流程
    java计算机毕业设计用户行为自动化书籍推荐系统源码+系统+mysql数据库+lw文档+部署
    【WFA】【WIFI6】HE-5.31.2_6G Fail
    显示控件——AV输入显示
    WRFDA资料同化实践技术应用
  • 原文地址:https://blog.csdn.net/weixin_41802023/article/details/128167090