Ответ 1
Убедитесь, что вы правильно настроили исходную и целевую
android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
У меня странная проблема и я не знаю, как ее разрешить.
У меня есть интерфейс с методом по умолчанию, например:
public interface ITest{
default String getText(){
return "ITest";
}
}
и класс, который реализует этот интерфейс, например:
public class TestClasssss implements ITest{
private String text;
}
И я пытаюсь использовать этот класс в своем проекте тестирования модулей приложений.
Итак, если я копирую эти классы внутри моего проекта android unit test, он компилируется нормально, и все работает как ожидалось, однако, если этот класс и интерфейс объявлены в папке исходного кода приложения, приложение не компилируется и не сбрасывается с помощью
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:[email protected]'
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
}
}
Я имел дело с одной и той же проблемой, это, по-видимому, какой-то конфликт между скомпилированной исходной версией java, принятой в android, и результатом, созданным кодом, скомпилированным с помощью retrolambda.
Проблема возникает при использовании нотации default
для метода функциональных интерфейсов.
Там какая-то ограниченная поддержка этого в плагине retrolambda, цитируя readme of repo (orfjackal/retrolambda):
retrolambda.defaultMethods Использовать ли по умолчанию методы и статические методы на интерфейсах. ОГРАНИЧЕНИЯ: Все обратные интерфейсы и все классы, которые реализуют их или вызвать их статические методы, должны быть переданы вместе, с одним исполнением Retrolambda. Отключено по умолчанию. Включить, установив значение "true"
Итак, вы можете попробовать использовать это в своем файле Android-модуля build.gradle
:
...
android {
...
}
retrolambda {
defaultMethods = true
}
В моем случае это не работает, но мой сценарий отличается от вашего. У меня был код retrolambda в одном проекте библиотеки, а затем я попытался использовать его в другом проекте приложения.
Также я не мог заставить компилятор Jack and Jill работать (есть поддержка java8 с поддержкой Jack, см. Включить Java 8 и Jack Toolchain на ссылке android), один критический "NullPointer" поднимается на ./gradlew assembleDebug
, поэтому я предлагаю избежать jackOptions
на данный момент.
Удачи!
Я думаю, что вам, вероятно, нужно включить компилятор Jack
. Вам необходимо следующее:
Ваш gradle должен выглядеть примерно так:
android {
...
defaultConfig {
...
jackOptions {
enabled true
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
Это Страница функций Java 8 Language в документации по Android
Вы уверены, что ваша сборка gradle использует jdk1.8 +? Похоже, что сборка пытается использовать класс, который был построен с использованием 1.8, но тестируется во время сборки, используя более низкую версию.
попробовать:
gradle clean build
ИЛИ
gradlew clean build
Если вы используете Android Studio, попробуйте очистить проект, а затем выполните проект. Если это тоже не помогает, нажмите "Файл" → "Недействительный кеш/перезагрузка". Это должно помочь