我有一个继承自Android的TextWatcher
的接口(interface),仅实现afterTextChanged
方法。我已经在项目中启用了Java 8支持,并在build.gradle
文件中添加了源和目标兼容性选项,但是即使它在调试版本中可以正常工作,但在我测试的每个设备上的发行版本中都无法实现。我首先在Play Console的发布前报告中注意到了这一点,并再次通过Firebase的测试实验室进行了测试,但每个设备仍然抛出AbstractMethodError
并导致崩溃。
这是我的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);
}
这是使用此接口(interface)的代码部分:
mSomeEditText.addTextChangedListener((AfterTextChangedListener) editable -> {
// Logic using 'editable'.
});
这是崩溃的Logcat输出:
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支持接口(interface)中的默认方法。
这是我的模块级
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
}
知道为什么会发生这种情况,以及如何解决吗?
最佳答案
你可以试试这个吗-
public interface AfterTextChangedListener extends TextWatcher {
@Override
void afterTextChanged(Editable s);
@Override
void beforeTextChanged(CharSequence s, int start, int count, int after);
@Override
void onTextChanged(CharSequence s, int start, int before, int count);
}
对我来说很好。