When instantiating a class that has code to explicitly call a default method for an interface that it implements, a java.lang.VerifyError
is thrown. This happens on Kitkat (API 19), but Lollipop and more recent versions work fine. The default method I'm working with was added in Android 12 (API 31), but I have a build version check, so that line won't even execute on earlier versions, but Kitkat still throws the error.
public class MyInputConnection implements InputConnection {
private void foo() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
SurroundingText surroundingText = InputConnection.super.getSurroundingText(1, 1, 0);
//...
}
}
}
MyInputConnection ic = new MyInputConnection(this); // error thrown here
Logs before the error:
W/dalvikvm: DexOpt: method is in an interface
I/dalvikvm: Could not find method android.view.inputmethod.InputConnection.getSurroundingText, referenced from method com.ewittman.example.MyInputConnection.foo
W/dalvikvm: VFY: unable to resolve virtual method 44: Landroid/view/inputmethod/InputConnection;.getSurroundingText (III)Landroid/view/inputmethod/SurroundingText;
VFY: rejecting opcode 0x6f at 0x0008
VFY: rejected Lcom/ewittman/example/MyInputConnection;.foo ()V Verifier rejected class Lcom/ewittman/example/MyInputConnection;
Error:
java.lang.VerifyError: com/ewittman/example/MyInputConnection
Why is this error getting thrown on Kitkat? Since the line of code to call the default method won't even be executed on Kitkat, I'd expect the class to instantiate without error.
I could create a new dummy implementation of the interface that doesn't override the default method so I can call that, but that doesn't seem like a very clean solution. Is there a better way to allow directly calling the default method for versions that include the method that won't break older versions?