【问题标题】:Lambda expressions crash with IncompatibleClassChangeError in Android when using jack使用 jack 时,Lambda 表达式在 Android 中因 IncompatibleClassChangeError 而崩溃
【发布时间】:2016-12-27 19:48:38
【问题描述】:

我在我的 Android 项目中使用 Java 8。我已经设置了 Jack(在 android 应用程序模块中)和 Retrolambda(在其他模块中)。

我遇到的问题是,当我尝试使其使用类变量(并且我可以在任何模块中重现它)时,我的 Lambda 表达式在一个特定场景中崩溃,在所有其他情况下它按预期工作。也许这是一种标准的 Java 行为,但到目前为止我找不到任何解释。有谁知道问题出在哪里? 我的课和下面的崩溃:

public class LambdaBugTest {

    private final String parentClassVariableString = "parentClassVariableString";

    public void testLambdas() {

        // ----------- THESE WORK OK --------------
        final Functional simpleLambdaWorks = text -> System.out.print(text);
        final Functional methodReferenceWorks = System.out::print;
        final Functional interfaceWithClassParamWorks = new Functional() {
            @Override
            public void doSomething(String text) {
                System.out.print(text + " " + parentClassVariableString);
            }
        };
        // -----------------------------------------

        // ----------- THIS ONE CRASHES ------------
        final Functional lambdaWithClassParamCrashes = text -> System.out.print(text + " " + parentClassVariableString);
        // -----------------------------------------

        simpleLambdaWorks.doSomething("Text from simpleLambdaWorks");
        methodReferenceWorks.doSomething("Text from methodReferenceWorks");
        interfaceWithClassParamWorks.doSomething("Text from interfaceWithClassParamWorks");
        lambdaWithClassParamCrashes.doSomething("Text from lambdaWithClassParamCrashes");
    }

    private interface Functional {
        void doSomething(String text);
    }
}

崩溃日志:

08-21 00:27:41.564 25752-25752/debug E/AndroidRuntime: FATAL EXCEPTION: main
        Process: debug, PID: 25752
        java.lang.IncompatibleClassChangeError: The method 'void data.api.mapper.LambdaBugTest.data_api_mapper_LambdaBugTest_lambda$testLambdas$1(java.lang.String)' was expected to be of type direct but instead was found to be of type virtual (declaration of 'java.lang.reflect.ArtMethod' appears in /system/framework/core-libart.jar)
        at data.api.mapper.LambdaBugTest.access$lambda$1(LambdaBugTest.java)
        at data.api.mapper.LambdaBugTest$$Lambda$5.doSomething(Unknown)
        at data.api.mapper.LambdaBugTest.testLambdas(LambdaBugTest.java:27)
        at home.presentation.HomeActivity.onCreate(HomeActivity.java:47)
        at android.app.Activity.performCreate(Activity.java:5990)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
        at android.app.ActivityThread.access$800(ActivityThread.java:151)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5254)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

【问题讨论】:

  • 您是否在使用 retrolambda 与 jack 编译器进行猜想?两者应该一起使用吗?我认为 jack 编译器确实带来了 java 8 api 支持(lambdas,以及所有 retrolambda 所做的)。我可能是错的,只是想知道您对此了解多少以及这是否会导致您的问题?
  • 我与 Jack 有相同的问题和异常消息,但我没有使用 Retrolambda。 Jack 似乎不喜欢像 () -> instanceVariable = localVariable 这样的实例变量赋值的表达式 lambda
  • 我也遇到了这个问题——不使用 Retro Lambda,只使用 jack 编译器

标签: android lambda java-8 retrolambda android-jack-and-jill


【解决方案1】:

Google 不再支持 android-jack。

不再支持 Jack,您应该首先禁用 Jack 以使用默认工具链中内置的 Java 8 支持

Android Studio 3.0 及更高版本支持 Lambda 表达式。配置 build.gradle 文件:

android {
...
// Configure only for each module that uses Java 8
// language features (either in its source code or
// through dependencies).
compileOptions {
  sourceCompatibility JavaVersion.VERSION_1_8
  targetCompatibility JavaVersion.VERSION_1_8
 }
}

注意:如果 Android Studio 检测到您的项目正在使用 Jack、Retrolambda 或 DexGuard,IDE 将使用这些工具提供的 Java 8 支持。但是,请考虑迁移到默认工具链

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-06-01
    • 2012-02-22
    • 1970-01-01
    • 1970-01-01
    • 2013-12-20
    • 1970-01-01
    • 2011-07-03
    • 2016-02-07
    相关资源
    最近更新 更多