当我们在调试模式(没有testCoverageEnabled = true)运行时,应用程序按预期工作.但是当我们使用testCoverageEnabled = true运行不同的配置时,应用程序崩溃并出现以下错误
java.lang.NoSuchMethodError: No static method $$triggerInterfaceInit()V in class Lcom/ui/viewholders/CAViewContract$$CC; or its super classes (declaration of 'ui.viewholders.CAViewContract$$CC' appears in /data/app/SMCXbiLYvHb1Kk08Kee__g==/base.apk) at home.c.CCFragment.<clinit>(Unknown Source:0) at home.HomePageCardProvider.getFragment(HomePageCardProvider.java:17) at home.HomeFragment.handleCardFragment(HomeFragment.java:172)
注意:
1. JaCoCo版本:“0.8.0”
2.操作系统:Android with minSdk 21
如果我们将minSdk更改为24,并且testCoverageEnabled = true本身,则它正在工作.我们无法弄清楚确切的问题.
解决方法
示例:假设这些定义:
class A implements DerivedInterface /*,...*/ { @Override public void methodFromBaseInterface() { DerivedInterface.super.methodFromBaseInterface(); // Error: // NoSuchMethodError: No static method methodFromBaseInterface } // ... } interface DerivedInterface extends BaseInterface { // ... // `methodFromBaseInterface` hasn't overriden here. } interface BaseInterface { default void methodFromBaseInterface() { /* ...*/ } // ... }
然后执行:
A a = new A(); a.methodFromBaseInterface(); // This cause above error!
而你在上述点上得到错误!
(边注:您可能需要在DerivedInterface中定义至少一个方法,以避免在运行时获取NoClassDefFoundError!)
这类似于一个错误!我们使用超级关键字.为什么要预期静态方法?!!另一点是上面的代码没有任何问题,您可以在任何Java 8兼容环境中运行它没有任何问题!
我认为这个问题与Android平台中Java 8语言API的不完全支持有关:
Android Studio 3.0 and later supports all Java 7 language features and a subset of Java 8 language features that vary by platform version.
在that page中特别注意Java 8 Language API和兼容的minSdkVersion表:
java.lang.FunctionalInterface
: API level 24 or higher.
我找到的解决方法:
>如果您有权访问DerivedInterface的定义,只需覆盖methodFromBaseInterface并将其显式委托给其超级接口:
interface DerivedInterface extends BaseInterface { @Override default void methodFromBaseInterface() { BaseInterface.super.methodFromBaseInterface(); } // ... }
>定义一个实现BaseInterface并从中派生A的中间类.然后运行methodFromBaseInterface间接抛出中间类:
class MiddleClass /*extends B*/ implements BaseInterface {} class A extends MiddleClass implements DerivedInterface { @Override public void methodFromBaseInterface() { super.methodFromBaseInterface(); // Indirectly from `MiddleClass` } // ... }
注意:如果您的A类之前有一个名为B的超级,则取消注释/ *扩展B * /.