NoClassDefFoundError, когда я использую lambda для перемещения массива String

Я получил ошибку при использовании lambda для перемещения массива String.

java.lang.NoClassDefFoundError: com.twsz.app.ivybox.alarm.CreateOrUpdateAlarmActivity$$Lambda$1
at com.twsz.app.ivybox.alarm.CreateOrUpdateAlarmActivity.initView(CreateOrUpdateAlarmActivity.java:143)
at com.twsz.app.ivybox.alarm.CreateOrUpdateAlarmActivity.onCreate(CreateOrUpdateAlarmActivity.java:73)

Это мой код. Я знаю, что это нормально для традиционного способа перемещения массива String, но почему это происходит, когда я использую лямбду.

    String[] days = dayOfWeek.split(",");
    Arrays.asList(days).forEach(day->{
        int index = Integer.valueOf(day) -1;
        checkBoxList.get(index).setChecked(true);
    });//where happens NoClassDefFoundError

Мой файл build.gradle

   android {
        compileSdkVersion 25
        buildToolsVersion "25.0.2"
        defaultConfig {
            applicationId "com.twsz.app.ivybox"
            minSdkVersion 14
            targetSdkVersion 25
            versionCode 1
            versionName "1.0"
            testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
            vectorDrawables.useSupportLibrary = true
        }

        compileOptions {
            sourceCompatibility JavaVersion.VERSION_1_8
            targetCompatibility JavaVersion.VERSION_1_8
        }

        dataBinding {
            enabled = true
        }
    }

Спасибо за любую помощь.

Ответы

Ответ 1

     *
     * @param action The action to be performed for each element
     * @throws NullPointerException if the specified action is null
     * @since 1.8
     */
    default void forEach(Consumer<? super T> action) {
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }

forEach - метод по умолчанию, его поддерживает только java8.

Android не поддерживает все функции языка Java 8. Однако при разработке приложений, ориентированных на Android 7.0 (API-уровень 24), доступны следующие функции:

Методы по умолчанию и статические интерфейсы
Лямбда-выражения (также доступны на уровне API 23 и ниже)
Повторяющиеся аннотации Ссылки на методы (также доступны на уровне API 23 и ниже)
Тип Аннотации (также доступны на уровне API 23 и ниже)

По умолчанию Android поддержки и статические методы интерфейса, но она нуждается в уровне API 24.More подробности здесь

defaultConfig {
            applicationId "com.twsz.app.ivybox"
            minSdkVersion 14 // Your minSdkVersion is less than 24
            targetSdkVersion 25
            versionCode 1
            versionName "1.0"
            testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
            vectorDrawables.useSupportLibrary = true
        }

Когда вы запустите свое приложение в системе менее 24, вы получите это исключение. так что вы лучше измените другой путь. Традиционный цикл или Rxjava2.

Ответ 2

Метод forEach доступен только в Android N, вы не можете использовать какой-либо API с Java 8 до SDK 24.

Даже если вы используете Retrolambda или Jack.

Вам нужно использовать регулярный цикл.

Ответ 3

Согласно Android, если вы хотите использовать lambdas, вам нужно установить API-интерфейс Targe на уровень ниже 23 (ваш в настоящее время установлен на 25), а затем используйте цепочку Jacktool.

В документах:

Android не поддерживает все функции языка Java 8. Однако при разработке приложений, ориентированных на Android 7.0 (API-уровень 24), доступны следующие функции:

  • Методы по умолчанию и статические интерфейсы
  • Лямбда-выражения (также доступны на уровне API 23 и ниже)
  • Повторяющиеся аннотации
  • Ссылки на методы (также доступны на уровне API 23 и ниже)
  • Тип Аннотации (также доступны на уровне API 23 и ниже)

Примечание. Примечание. Информация об аннотации типа доступна во время компиляции, но не во время выполнения. Кроме того, платформа поддерживает TYPE в API 24 и ниже, но не ElementType.TYPE_USE или ElementType.TYPE_PARAMETER..

Чтобы проверить лямбда-выражения, ссылки на методы и аннотации типов на более ранних версиях Android, перейдите в файл build.gradle и установите для compileSdkVersion и targetSdkVersion значение 23 или ниже. Вам все равно нужно включить инструментальную цепочку Jack для использования этих функций Java 8.

Ответ 4

Для использования функций Java 8 вам необходимо включить Jack Toolchain

  defaultConfig {
    ...
    jackOptions {
      enabled true
    }
  }

Дополнительную информацию см. В документации