我有一个奇怪的问题,不知道如何解决。
我有一个带有默认方法的接口,如下所示:
public interface ITest{
default String getText(){
return "ITest";
}
}
和实现该接口的类,如下所示:
public class TestClasssss implements ITest{
private String text;
}
我试图在我的应用程序单元测试项目中使用这个类。
所以,如果我将这些类复制到我的android单元测试项目中,它会正常编译,一切正常工作,然而,如果这个类和接口声明在应用程序源文件夹中,应用程序不会编译和崩溃Error:(30, 10) error: cannot access ITest bad class file: ~ITest.class
default method found in version 50.0 classfile
Please remove or make sure it appears in the correct subdirectory of the classpath.
那么,我该如何修复这个奇怪的行为呢?
我的graddle配置是这样的:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'me.tatarka:gradle-retrolambda:3.2.5'
}
}
repositories {
mavenCentral()
mavenLocal()
maven {
url = "https://oss.sonatype.org/content/repositories/snapshots/"
}
jcenter()
}
apply plugin: 'com.android.application'
apply plugin: 'me.tatarka.retrolambda'
apply plugin: 'realm-android'
apply plugin: 'com.neenbedankt.android-apt'
apt {
arguments {
androidManifestFile variant.outputs[0]?.processResources?.manifestFile
}
}
android {
compileSdkVersion 24
buildToolsVersion '24.0.1'
defaultConfig {
applicationId "io.projectname"
targetSdkVersion 24
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
debuggable true
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt')
}
}
testOptions {
unitTests.returnDefaultValues = true
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
dataBinding {
enabled = true
}
sourceSets {
main {
res.srcDirs =
[
'src/main/res/controls',
'src/main/res/fragments',
'src/main/res/activities',
'src/main/res/views',
'src/main/res'
]
}
}
}
ext {
JUNIT_VERSION = '4.12'
DAGGER_VERSION = '2.2'
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
testCompile 'junit:junit:4.12'
testCompile 'org.mockito:mockito-core:2.0.111-beta'
testCompile "org.robolectric:robolectric:3.1.1"
compile 'com.android.support:appcompat-v7:24.2.0'
compile 'com.android.support:design:24.2.0'
compile 'com.roughike:bottom-bar:1.3.4'
compile 'com.aurelhubert:ahbottomnavigation:1.2.3'
compile 'joda-time:joda-time:2.9.4'
compile 'com.annimon:stream:1.0.9'
compile 'com.kyleduo.switchbutton:library:1.4.1'
compile 'io.reactivex:rxandroid:1.2.0'
compile 'io.reactivex:rxjava:1.1.5'
compile 'com.jakewharton.rxbinding:rxbinding:0.4.0'
compile('eu.davidea:flexible-adapter:5.0.0-SNAPSHOT') {
changing = true
}
compile 'com.github.aakira:expandable-layout:1.5.1@aar'
compile "cn.aigestudio.wheelpicker:WheelPicker:1.1.2"
compile 'net.sf.biweekly:biweekly:0.5.0'
//Dagger dependencies started
compile "com.google.dagger:dagger:$DAGGER_VERSION"
apt "com.google.dagger:dagger-compiler:$DAGGER_VERSION"
provided 'javax.annotation:jsr250-api:1.0'
compile 'javax.inject:javax.inject:1'
testCompile "junit:junit:$JUNIT_VERSION"
testApt "com.google.dagger:dagger-compiler:$DAGGER_VERSION"
//Dagger dependencies finished
provided 'org.projectlombok:lombok:1.16.10'
}
确保正确设置源和目标兼容性
android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
我正在处理同样的问题,它似乎是在android上接受的编译java源代码版本和用retrolambda编译的代码产生的输出之间的某种冲突。当您将default
符号用于函数接口方法时,问题就出现了。在retrolambda插件中有一些有限的支持,引用repo的自述(orfjackal/retrolambda):
retrolambda.defaultMethods是否在接口上反向移植默认方法和静态方法。限制:所有后移植接口和所有实现它们或调用它们的静态方法必须一起反向移植,使用Retrolambda执行一次。默认为关闭。设置为true
所以你可以尝试在你的android模块的build.gradle
文件中使用这个:
...
android {
...
}
retrolambda {
defaultMethods = true
}
在我的情况下,这不起作用,但我的情况与你的完全不同。我在一个库项目上有retrolambda代码,然后试图在另一个应用程序项目上使用它。
我也不能得到杰克& &;Jill编译器的工作(有一些java8支持与杰克启用,见启用Java 8功能和杰克工具链在android参考),一个神秘的"NullPointer"上升在./gradlew assembleDebug
,所以我建议现在避免jackOptions
。
祝你好运!
我认为您可能需要启用Jack
编译器。您需要以下内容:
- Android Studio> 2.1
- 默认方法仅在目标API Level 24 时可用
你的gradle需要看起来像这样:
android {
...
defaultConfig {
...
jackOptions {
enabled true
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
这是Android文档中的Java 8语言特性页面
我在使用dex2jar后遇到了这个问题。根据https://gitlab.ow2.org/asm/asm/blob/master/asm/src/main/java/org/objectweb/asm/Opcodes.java#L264, JVM字节码的版本50代表Java 1.6,而我的索引文件被设计为在版本52(1.8)上运行。我使用了另一个dex2jar实用程序(它应该适用于任何jar,而不仅仅是dex)将版本更改为1.8。源代码在https://github.com/pxb1988/dex2jar/blob/2.x/dex-tools/src/main/java/com/googlecode/dex2jar/tools/ClassVersionSwitch.java,命令是d2j-class-version-switch.sh 8 <source jar> <destination jar>
。
你确定你的gradle构建是使用jdk1.8+吗?似乎构建是试图利用一个类,使用1.8构建,但在构建期间使用较低版本进行测试。
试题:
gradle clean build
或
gradlew clean build
如果你正在使用Android Studio尝试清理项目,然后构建项目。如果没有帮助,然后点击文件->"无效缓存/重启"。