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

时间:2017-05-04 06:00:20

标签: java android lambda

当我使用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数组的方法没问题,但是为什么在使用lambda时会发生这种情况。

    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
        }
    }

感谢您的帮助。

5 个答案:

答案 0 :(得分:10)

     *
     * @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)的应用时,可以使用以下功能:

     

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

Android支持默认和静态接口方法,但它需要API级别24.更多详细信息here

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。

答案 1 :(得分:9)

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

即使您使用的是Retrolambda或Jack。

您需要使用常规for循环。

答案 2 :(得分:7)

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

根据docs

  

Android不支持所有Java 8语言功能。然而   开发应用定位时,可以使用以下功能   Android 7.0(API级别24):

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

注意:注意:类型注释信息在编译时可用,   但不是在运行时。此外,该平台支持API 24和中的TYPE   下面,但不是ElementType.TYPE_USE或ElementType.TYPE_PARAMETER ..

     

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

答案 3 :(得分:3)

要使用Java 8功能,您需要启用Jack Toolchain

  defaultConfig {
    ...
    jackOptions {
      enabled true
    }
  }

有关详细信息,请参阅documentation

答案 4 :(得分:2)

来源:https://developer.android.com/guide/platform/j8-jack.html

如果你想在android中使用lambda,你可以像这样添加gradle选项 enter image description here