Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NoSuchMethodError with Android Lambdas

Tags:

android

lambda

I'm seeking to use Lambda expressions in my Android project (min sdk: 16, target sdk: 25), but running into many issues.

The first problem is that I am developing and debugging my app using an emulator, deploying and fixing bugs multiple times, when, out of the blue, the application will stop loading altogether.

I get the following stacktrace in my log:

java.lang.NoSuchMethodError: No direct method (Ljava/lang/Object;)V in class Lcom/androidtest/-$Lambda$1; or its super classes (declaration of 'com.androidtest.-$Lambda$1' appears in /data/app/com.androidtest-2/base.apk)

I've enabled the use of lambda expression as described in the android documentation with the following code in my app/build.gradle file:

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.2"
    defaultConfig {
        applicationId "com.gfs.mp3lab"
        minSdkVersion 16
        targetSdkVersion 25
        ...
    }
    ...

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

I took Parth Pandya's suggestion and added the jackOptions paramter in my build.gradle file and believed that to fix the problem, but after rebuilding my project I now sproadically get a different error:

java.lang.IncompatibleClassChangeError: Class 'com.gfs.jotsalot.-$Lambda$1' does not implement interface 'java.lang.Runnable' in call to 'void java.lang.Runnable.run()' (declaration of 'android.os.Handler' appears in /system/framework/framework.jar) at android.os.Handler.handleCallback(Handler.java:751) at android.os.Handler.dispatchMessage(Handler.java:95)

Replacing the lambda expression appears to fix the problem, so going from

() -> { Log.i(TAG, "Hey There"); }

to

new Runnable() {
    @Override
    public void run() {
        Log.i(TAG, "Hey There");
    }
}

works. I'm doing this in a threaded application so I'm not sure if that's the reason for the error and so far I have only tried it on an emulator. Rebuilding the project fixes the problem but that is very time consuming and the hassle has been detrimental to the point where I am removing all of them from my project.

So far I have only tested inside of an emulator and am uncertain if it would affect a genuine phone environment. Because these lambda expressions work just fine (until they don't) I think it is safe to conclude that this is a bug. I was just wondering if it is a known one and if there are any workarounds for it.

like image 682
IcedDante Avatar asked Feb 07 '17 04:02

IcedDante


2 Answers

In your build.gradle file you are missing jackOptions enabled to true just add this to your defaultConfig like below and I think it should work.

android {
 defaultConfig {
     applicationId "com.gfs.mp3lab"
     minSdkVersion 16
     targetSdkVersion 25
     jackOptions {
        enabled true
     }
     ...
 }
 ...

  compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
  }
}
like image 186
Parth Pandya Avatar answered Oct 13 '22 02:10

Parth Pandya


Parth's answer was helpful, but in the end I kept getting runtime errors using lambda expressions no matter what I seemd to do. Because the Intellij-based IDE represents implementations of single function Interfaces as lambdas visually, I opted to just remove all of them from my project rather than deal with the headache.

like image 35
IcedDante Avatar answered Oct 13 '22 02:10

IcedDante