重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
前几天同事遇到一个非常诡异的报错,紧急处理后,趁着周末仔细研究了一下原因,觉得还挺有意思的,所以记录一下
成都创新互联于2013年创立,是专业互联网技术服务公司,拥有项目成都网站建设、成都做网站网站策划,项目实施与项目整合能力。我们以让每一个梦想脱颖而出为使命,1280元陆丰做网站,已为上家服务,为陆丰各地企业和个人服务,联系电话:028-86922220部分机型反馈崩溃问题问题背景:在一个SDK工程,前几天客户那边报了一个崩溃问题,并且在API 28以上的系统才会:No virtual method keySet()Ljava/util/concurrent/ConcurrentHashMap$KeySetView
查看调用栈后发现调用到了ConcurrentHashMap#keySet
,顺着调用发现这是一个JDK1.8的API
这么看起来应该是JDK7 和JDK8的一个兼容问题,具体的问题需要继续往下看
第一反应是是不是因为当前工程是JDK7的工程导致的?因为之前也在JDK7的工程上集成过JDK8的三方库,因为字节码不匹配导致崩溃,当时的解决方案有几种:
- 将工程和模块的JavaVersion设置为 Java7语言
- defalutConfig 里配置 jackOptions{ enable = true}
- 升级至Java8,可能遇到乱七八糟的问题可以通过一起升级gradle版本解决
但是想想也不对,因为我是作为SDK的提供方,提供的应该也是JDK7的字节码,反编译后查看字节码也确实是JDK7的,虽然查看字节码确实有KeySetView,但是提供给JD8的工程用应该也不至于崩溃吧
回想起APK的打包流程,最后打包成dex文件的时候好像是没看到有JDK版本的区别,并且JDK8的工程也是可以兼容老的机器的,这就想到了打包时的一个脱糖操作(对lambda表达式的处理也是如此),回顾一下相关的知识点:
对比与排查
- DX:class文件转化为dex
- D8:脱糖、class文件转换为dex
- R8:整合了Proguard和D8 ,减少了一个编译步骤,同时保留了字节码优化能力
了解到上面的知识,随即仔细的看了下出SDK的分支,结果发现…
这居然是还是个java工程!!!那自然没有脱糖相关的操作了,再看下输出的jar
升级成android library 工程后打包的aar,输出产物正常!撒花
总结最后最后,如果觉得有帮助欢迎点个👍或关注~
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧