Я написал библиотеку AAR, которая реализует некоторые функции уведомлений Android. Когда я пытаюсь создать уведомление на устройствах под управлением Android O (26+), я получаю следующую ошибку:
java.lang.NoSuchMethodError: No direct method <init>(Landroid/content/Context;Ljava/lang/String;)V in class Landroid/support/v4/app/NotificationCompat$Builder; or its super classes (declaration of 'android.support.v4.app.NotificationCompat$Builder' appears in /data/app/org.myapp-VuZkSUvRuAyiaIG5th_Mrw==/base.apk)
at org.myapp.notificationutility.NotificationService.createNotification(NotificationService.java:208)
at org.myapp.notificationutility.NotificationService.showNotification(NotificationService.java:169)
at org.myapp.notificationutility.NotificationService.onStartCommand(NotificationService.java:117)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3668)
at android.app.ActivityThread.access$1600(ActivityThread.java:200)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1682)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6680)
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)
Я убедился, что мой код соответствует тому, что показано на https://developer.android.com/training/notify-user/build-notification#java
Исключение происходит в new NotificationCompat.Buider
строке new NotificationCompat.Buider
ниже. Мой код:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
String name = "My App";
NotificationChannel channel = new NotificationChannel(
CHANNEL_ID,
name,
NotificationManager.IMPORTANCE_LOW);
channel.setLightColor(Color.CYAN);
channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
NotificationManager notificationManager =
(NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.createNotificationChannel(channel);
}
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(icon)
.setContentTitle(notificationTitle)
.setContentText(notificationContent)
.setPriority(NotificationCompat.PRIORITY_LOW)
.setAutoCancel(false)
.setOngoing(true);
Мой файл Gradle:
apply plugin: 'com.android.library'
android {
compileSdkVersion 28
buildToolsVersion "28.0.3"
defaultConfig {
minSdkVersion 18
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compileOnly fileTree(dir: 'libs', include: ['*.jar'])
androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
implementation 'com.android.support:support-compat:28.+'
testImplementation 'junit:junit:4.12'
}
Ошибка указывает, что new NotificationCompat.Buider
конструктор new NotificationCompat.Buider
который принимает контекст и String CHANNEL_ID
, не существует при запуске на устройстве, но Android Studio создает модуль без каких-либо ошибок. Если Android Studio создает AAR без ошибок (метод существует в библиотеке при сборке), разве метод не должен существовать во время выполнения?
Мое предположение заключается в том, что приложение, в котором вы используете эту библиотеку, принудительно использует версию библиотеки поддержки, более раннюю, чем 26.1.0, даже если ваша библиотека указывает, что для нее требуется версия 28.0.0 или выше. Вы можете проверить это, запустив:
./gradlew :app:dependencyInsight --configuration releaseCompileClasspath --dependency support-compat
Который должен показать вам версии, которые вводятся, и откуда. Обратите внимание, что ваша конфигурация может отличаться, если у вас есть несколько productFlavors
в конфигурации вашего приложения (например, если у вас есть --configuration productionReleaseCompileClasspath
"production", вы бы указали --configuration productionReleaseCompileClasspath
).
По сути, ваша библиотека компилируется с support-compat
28. + (что бы ни разрешало в то время - я бы настоятельно рекомендовал вместо этого использовать фиксированный номер версии), но при включении в приложение конфигурация приложения использует другую версию библиотека support-compat
которой ваша библиотека несовместима. Вам нужно будет обновить приложение, чтобы обеспечить его использование support-compat
compat 26.1.0 или более поздней версии.