Android 接口的default 方法运行时报错AbstractMethodError
创始人
2024-03-18 09:24:17
0

【问题描述:接口default方法AbstractMethodError】

记录一个Android项目中遇到的问题,我们通过exclude方式重写了一个依赖,改用本地的实现,其中一个接口的default 方法,在运行时报错:AbstractMethodError,也就是没有找到这个default的实现。
在这里插入图片描述

【定位原因:exclude导致d8不注入default方法的实现】

查看了exclude之后的apk里本地实现该default接口的class文件,发现Android d8工具实现了对Jave 8语言特性的兼容实现,实现方式是把接口的 default 方法生成了一个$-CC的合成类,所有继承这个接口的类里注入了一个合成方法,该方法调用了这个$-CC类里的实现。(编译过程)

而我们exclude之后的apk里lib2实现该default接口的class文件,继承这个接口的类里没有注入这个合成方法,导致直接调用了接口的abstract定义,所以报出AbstractMethodError。

进一步实验发现,只要在依赖 lib2 时exclude了 lib1,即使app里重新依赖lib1,都会导致d8无法实现对 lib2 里default方法的注入。

所以问题的原因进一步需要定位:【为什么exclude之后,d8无法实现对 lib2 里default方法的注入?】

【解决方案:substitute】

笔者还没能分析出【为什么exclude之后,d8无法实现对 lib2 里default方法的注入?】这个问题,但是从另一个思路解决了这个问题,就是既然想把lib1的实现替换为本地的,可以建立一个子模块project(‘:local_lib1’),使用gradle的substitute语法来替换module lib1的依赖为project(‘:local_lib1’):

configurations.all {resolutionStrategy.dependencySubstitution {substitute module("com.harold.group:lib1") using project(":local_lib1") because "some reason"}
}

这正是gradle推荐使用substitute的场景:

One use case for dependency substitution is to use a locally developed version of a module in place of one that is downloaded from an external repository. This could be useful for testing a local, patched version of a dependency.

最后的建议:

  1. 不要过度使用exclude,仅当你确定代码中真的不需要这个module的时候,否则即使你在其他地方又依赖了进来,也会对代码的编译产生影响,例如本文中的default接口
  2. 想要移除远程module依赖,替换为本地的实现时,非常适合使用 substitute
  3. 如果只是想指定module版本,考虑使用自定义依赖解析

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...
有效的括号 一、题目 给定一个只包括 '(',')','{','}'...
【Ctfer训练计划】——(三... 作者名:Demo不是emo  主页面链接:主页传送门 创作初心ÿ...