У меня есть интерфейс, который наследуется от Android TextWatcher
для реализации только afterTextChanged
метода. Я включил поддержку Java 8 в своем проекте и добавил параметры совместимости источника и цели в файл build.gradle
, но, несмотря на то, что он работает безупречно в отладочных сборках, он не работает в выпусках на всех протестированных устройствах. Я впервые заметил это в отчете перед запуском Play Console и снова протестировал в лаборатории тестирования Firebase, при этом каждое устройство бросает AbstractMethodError
, за которым следует cra sh.
Вот мой AfterTextChangedListener
:
import android.text.Editable;
import android.text.TextWatcher;
public interface AfterTextChangedListener extends TextWatcher {
@Override
default void beforeTextChanged(CharSequence s, int start, int count, int after) {
// Do nothing
}
@Override
default void onTextChanged(CharSequence s, int start, int before, int count) {
// Do nothing
}
@Override
void afterTextChanged(Editable s);
}
Вот часть кода, которая использует этот интерфейс:
mSomeEditText.addTextChangedListener((AfterTextChangedListener) editable -> {
// Logic using 'editable'.
});
Вот вывод Logcat для cra * sh:
FATAL EXCEPTION: main
Process: my.package.name, PID: 4096
java.lang.AbstractMethodError: abstract method "void android.text.TextWatcher.beforeTextChanged(java.lang.CharSequence, int, int, int)"
at android.widget.TextView.sendBeforeTextChanged(TextView.java:9704)
at android.widget.TextView.setText(TextView.java:5615)
at android.widget.TextView.setText(TextView.java:5571)
at android.widget.EditText.setText(EditText.java:122)
at android.widget.TextView.setText(TextView.java:5528)
at i.a.a.f.c.d1.b(Unknown Source:25)
at i.a.a.f.c.d1.b(Unknown Source:105)
at androidx.fragment.app.Fragment.g(Unknown Source:11)
at androidx.fragment.app.s.a(Unknown Source:35)
at androidx.fragment.app.m.a(Unknown Source:240)
at androidx.fragment.app.m.j(Unknown Source:2)
at androidx.fragment.app.m.i(Unknown Source:58)
at androidx.fragment.app.a.e(Unknown Source:171)
at androidx.fragment.app.m.a(Unknown Source:38)
at androidx.fragment.app.m.b(Unknown Source:120)
at androidx.fragment.app.m.c(Unknown Source:84)
at androidx.fragment.app.m.b(Unknown Source:31)
at androidx.fragment.app.a.c(Unknown Source:6)
at androidx.fragment.app.q.a(Unknown Source:4)
at c.u.a.b.c(Unknown Source:385)
at c.u.a.b.e(Unknown Source:2)
at c.u.a.b.onMeasure(Unknown Source:191)
at android.view.View.measure(View.java:23181)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6749)
at androidx.coordinatorlayout.widget.CoordinatorLayout.a(Unknown Source:0)
at com.google.android.material.appbar.b.a(Unknown Source:93)
at androidx.coordinatorlayout.widget.CoordinatorLayout.onMeasure(Unknown Source:275)
at android.view.View.measure(View.java:23181)
at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:715)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:461)
at android.view.View.measure(View.java:23181)
at androidx.drawerlayout.widget.DrawerLayout.onMeasure(Unknown Source:264)
at android.view.View.measure(View.java:23181)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6749)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at androidx.appcompat.widget.ContentFrameLayout.onMeasure(Unknown Source:156)
at android.view.View.measure(View.java:23181)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6749)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1535)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:825)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:704)
at android.view.View.measure(View.java:23181)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6749)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at android.view.View.measure(View.java:23181)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6749)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1535)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:825)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:704)
at android.view.View.measure(View.java:23181)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6749)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at com.android.internal.policy.DecorView.onMeasure(DecorView.java:716)
at android.view.View.measure(View.java:23181)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2727)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1580)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1864)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1468)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7208)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1004)
at android.view.Choreographer.doCallbacks(Choreographer.java:816)
at android.view.Choreographer.doFrame(Choreographer.java:751)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:990)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6694)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Force finishing activity my.package.name/.ui.activities.MainActivity
Я не Я понятия не имею, почему это происходит, особенно учитывая, что Android поддерживает методы по умолчанию в интерфейсах.
![Default and static interface methods: Any](https://i.stack.imgur.com/UK5ZK.png)
Вот мой уровень модуля build.gradle
:
apply plugin: 'com.android.application'
apply plugin: 'io.fabric'
android {
signingConfigs {
release {
// keystore credentials
}
}
compileSdkVersion 29
buildToolsVersion '28.0.3'
defaultConfig {
applicationId "my.package.name"
minSdkVersion 16
targetSdkVersion 29
multiDexEnabled true
versionCode 66
versionName "2020.2b1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
javaCompileOptions {
annotationProcessorOptions {
arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
}
}
}
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'androidx.multidex:multidex:2.0.1'
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.vectordrawable:vectordrawable:1.1.0'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
// Material
implementation 'com.google.android.material:material:1.2.0-alpha04'
implementation 'androidx.exifinterface:exifinterface:1.1.0'
implementation 'androidx.browser:browser:1.2.0'
// Room components
implementation 'androidx.room:room-runtime:2.2.3'
implementation 'androidx.preference:preference:1.1.0'
annotationProcessor 'androidx.room:room-compiler:2.2.3'
androidTestImplementation 'androidx.room:room-testing:2.2.3'
// SafeRoom
implementation "com.commonsware.cwac:saferoom.x:1.1.3"
// Lifecycle components
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
implementation "androidx.lifecycle:lifecycle-common-java8:2.2.0"
// Firebase
implementation 'com.google.firebase:firebase-core:17.2.2'
implementation 'com.google.firebase:firebase-ads:18.3.0'
implementation 'com.google.firebase:firebase-firestore:21.4.0'
implementation 'com.google.firebase:firebase-inappmessaging-display:19.0.3'
implementation 'com.google.firebase:firebase-messaging:20.1.0'
implementation 'com.google.firebase:firebase-perf:19.0.5'
implementation 'com.google.firebase:firebase-auth:19.2.0'
implementation 'com.google.firebase:firebase-storage:19.1.1'
implementation 'com.google.firebase:firebase-config:19.1.1'
implementation 'com.crashlytics.sdk.android:crashlytics:2.10.1'
//implementation('com.crashlytics.sdk.android:crashlytics:2.7.1@aar') {
// transitive = true
//}
implementation 'com.google.android.gms:play-services-auth:17.0.0'
implementation 'com.github.PhilJay:MPAndroidChart:v3.0.2'
implementation 'com.squareup.picasso:picasso:2.71828'
// implementation 'com.squareup.picasso:picasso:2.5.2'
implementation 'com.hootsuite.android:nachos:1.1.1'
implementation 'com.robertlevonyan.view:MaterialChipView:1.2.4'
implementation 'net.lingala.zip4j:zip4j:1.3.2'
implementation 'net.cachapa.expandablelayout:expandablelayout:2.9.2'
// RoundedImageView
implementation 'com.makeramen:roundedimageview:2.3.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation('androidx.test.espresso:espresso-core:3.1.0', {
exclude group: 'com.android.support', module: 'support-annotations'
})
testImplementation 'org.json:json:20190722'
implementation 'com.wdullaer:materialdatetimepicker:4.2.3'
// LeakCanary
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.0-beta-3'
}
apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.google.firebase.firebase-perf'
apply plugin: 'org.sonarqube'
sonarqube {
sonarqube {
properties {
// Some properties for sonarqube
}
}
}
Вот мой уровень проекта build.gradle
:
buildscript {
repositories {
google()
jcenter()
maven {
url 'https://maven.fabric.io/public'
}
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.3'
classpath 'com.google.gms:google-services:4.3.3'
classpath 'io.fabric.tools:gradle:1.26.1'
classpath 'com.google.firebase:perf-plugin:1.3.1'
classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.7.1"
}
}
allprojects {
repositories {
google()
jcenter()
maven { url "https://jitpack.io" }
maven {
url 'https://maven.google.com/'
}
maven {
url "https://s3.amazonaws.com/repo.commonsware.com"
}
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
Есть идеи, почему это происходит, и как это можно решить?