当我使用lambda遍历String数组时,NoClassDefFoundError

Cyr*_*rus 14 java lambda android

当我使用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)
Run Code Online (Sandbox Code Playgroud)

这是我的代码.我知道传统方式遍历String数组是可以的,但是为什么在使用lambda时会发生这种情况.

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

我的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
        }
    }
Run Code Online (Sandbox Code Playgroud)

谢谢你的帮助.

小智 11

     *
     * @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);
        }
    }
Run Code Online (Sandbox Code Playgroud)

forEach是默认方法,它只受java8支持.

Android不支持所有Java 8语言功能.但是,在开发面向Android 7.0(API级别24)的应用时,可以使用以下功能:

默认和静态接口方法
Lambda表达式(也可在API级别23及更低版本上使用)可
重复注释方法引用(也可在API级别23及更低版本上使用)
类型注释(也可在API级别23及更低版本上使用)

Android支持默认和静态接口方法,但它需要API级别24.更多细节在这里

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
        }
Run Code Online (Sandbox Code Playgroud)

当您在小于24的系统中运行应用程序时,您将获得该异常.所以你最好改变另一种方式.传统循环或Rxjava2.


Dim*_*zis 9

forEach 方法仅在Android N中可用,在SDK 24之前不能使用Java 8中的任何API.

即使你使用的是Retrolambda或Jack.

你需要使用常规for循环.


Bla*_*rai 7

根据Android,如果你想使用lambda,你需要将你的目标API设置为低于23(你的目前设置为25),然后使用Jacktool链.

根据文档:

Android不支持所有Java 8语言功能.但是,在开发面向Android 7.0(API级别24)的应用时,可以使用以下功能:

  • 默认和静态接口方法
  • Lambda表达式(也可在API级别23及更低版本上使用)
  • 可重复的注释
  • 方法参考(也可在API级别23及更低版本上获得)
  • 类型注释(也可在API级别23及更低版本上使用)

注意:注意:类型注释信息在编译时可用,但在运行时不可用.此外,该平台在API 24及更低版本中支持TYPE,但不支持ElementType.TYPE_USE或ElementType.TYPE_PARAMETER ..

要在早期版本的Android上测试lambda表达式,方法引用和类型注释,请转到build.gradle文件,并将compileSdkVersion和targetSdkVersion设置为23或更低.您仍然需要启用Jack工具链才能使用这些Java 8功能.