java.lang.VerifyError: Верifier отклонил класс на Lollipop при использовании релизного APK
Описание проблемы
Я получаю следующую ошибку при установке своего релизного APK на устройство с версией Android 5.x. Ошибка не возникает, когда я запускаю тот же код из Android Studio или на устройстве с версией 4.x.
java.lang.VerifyError: Verifier rejected class com.myapp.android.ui.activity.MainActivity$$ViewInjector due to bad method void com.myapp.android.ui.activity.MainActivity$$ViewInjector.reset(com.myapp.android.ui.activity.MainActivity) (declaration of 'com.myapp.android.ui.activity.MainActivity$$ViewInjector' appears in /data/app/com.myapp.android-2/base.apk)
at java.lang.Class.classForName(Class.java)
at java.lang.Class.forName(Class.java:308)
at java.lang.Class.forName(Class.java:272)
at butterknife.ButterKnife.findInjectorForClass(ButterKnife.java:298)
at butterknife.ButterKnife.inject(ButterKnife.java:271)
at butterknife.ButterKnife.inject(ButterKnife.java:184)
at com.myapp.android.ui.activity.MyDrawerActivity.onCreate(MyDrawerActivity.java:31)
В этом классе я использую инъекцию для моего Toolbar
и кастомного NavigationDrawer
:
@InjectView(R.id.toolbar) Toolbar mToolbar;
@InjectView(R.id.nav_drawer) MyNavigationDrawer mNavigationDrawer;
Ошибка возникает на строке 31:
ButterKnife.inject(this);
Существует ли что-то, что может отличаться в генерации кода ButterKnife при использовании команды gradle assembleRelease
? Я вообще не использую ProGuard.
Вот мои другие настройки сборки Android:
# Android SDK settings
ANDROID_BUILD_MIN_SDK_VERSION=14
ANDROID_BUILD_TARGET_SDK_VERSION=21
ANDROID_BUILD_SDK_VERSION=21
ANDROID_BUILD_TOOLS_VERSION=21.1.2
Logcat
I/art (21354): Verification error in void com.myapp.android.ui.activity.MainActivity$$ViewInjector.inject(butterknife.ButterKnife$Finder, com.myapp.android.ui.activity.MainActivity, java.lang.Object)
I/art (21354): void com.myapp.android.ui.activity.MainActivity$$ViewInjector.inject(butterknife.ButterKnife$Finder, com.myapp.android.ui.activity.MainActivity, java.lang.Object) failed to verify: register v4 has type Reference: com.myapp.android.ui.activity.MainActivity but expected Reference: com.myapp.android.ui.activity.LoggedInNavActivity
I/art (21354): Verification error in void com.myapp.android.ui.activity.MainActivity$$ViewInjector.reset(com.myapp.android.ui.activity.MainActivity)
I/art (21354): void com.myapp.android.ui.activity.MainActivity$$ViewInjector.reset(com.myapp.android.ui.activity.MainActivity) failed to verify: register v1 has type Reference: com.myapp.android.ui.activity.MainActivity but expected Reference: com.myapp.android.ui.activity.LoggedInNavActivity
E/art (21354): Verification failed on class com.myapp.android.ui.activity.MainActivity$$ViewInjector in /data/app/com.myapp.android-1/base.apk because: Verifier rejected class com.myapp.android.ui.activity.MainActivity$$ViewInjector due to bad method void com.myapp.android.ui.activity.MainActivity$$ViewInjector.reset(com.myapp.android.ui.activity.MainActivity)
Надеюсь на помощь в решении данной проблемы.
5 ответ(ов)
Очистка папки build
решила проблему. Не знаю, почему ART вызвал проблему, а Dalvik - нет.
Запуск задачи Gradle clean
не полностью очищал мою папку build
. Мне пришлось сделать это вручную, но для некоторых людей clean
может сработать.
В вашем случае метод, который упоминался в сообщении об ошибке как 'неправильный', содержал некоторые неизвестные проблемы. Переход от лямбды в Kotlin к обычному циклу решил мою проблему.
Вот как это выглядело до исправления (с ошибкой):
fun validZipCode(zipcode: String): Boolean {
val validRegexes = arrayOf(
"0[0-9]{1}[0-9]{2}",
"1[0-2]{1}[0-9]{2}",
"1[3-4]{1}[0-9]{2}",
"19[0-9]{2}",
"2[0-1]{1}[0-9]{2}"
)
return validRegexes.any { zipcode.matches(it.toRegex()) }
}
А вот так выглядит исправленный код:
fun validZipCode(zipcode: String): Boolean {
val validRegexes = arrayOf(
"0[0-9]{1}[0-9]{2}",
"1[0-2]{1}[0-9]{2}",
"1[3-4]{1}[0-9]{2}",
"19[0-9]{2}",
"2[0-1]{1}[0-9]{2}"
)
for (regex in validRegexes) {
if (zipcode.matches(regex.toRegex())) {
return true
}
}
return false
}
Как видно, после замены лямбды на обычный цикл, проблема исчезла.
Проблема с крашами вашего приложения на Android 5.1 может быть связана с новой D8 компилятором dex. Мне тоже приходилось сталкиваться с похожей ситуацией, и отключение D8 было единственным, что сработало для меня. Вот пошаговое решение:
- Если у вас еще нет, создайте файл
gradle.properties
в корне вашего проекта. - В этом файле добавьте следующую строку:
android.enableD8=false
После этого вы можете увидеть предупреждения о депрекации, но, надеюсь, Google исправит D8 до полного удаления старого DX компилятора. К сожалению, я не могу сказать, что конкретно в моем коде вызывает эту проблему. Я использую Android Studio 3.2.1 с версией gradle 4.6.
Кстати, я сообщил об этой ошибке, и разработчики Google уже занимаются ее исследованием. Если вы столкнулись с подобной проблемой, отключение D8 может быть временным решением.
У меня была такая же проблема с GoogleTagManager
.
java.lang.VerifyError: Версирующий отклонил класс com.google.android.gms.tagmanager.TagManager: com.google.android.gms.common.api.PendingResult com.google.android.gms.tagmanager.TagManager.loadContainerDefaultOnly(java.lang.String, int) не удалось проверить: com.google.android.gms.common.api.PendingResult com.google.android.gms.tagmanager.TagManager.loadContainerDefaultOnly(java.lang.String, int): [0x11] возвращает 'Ссылка: com.google.android.gms.tagmanager.zzp', но ожидалась 'Ссылка: com.google.android.gms.common.api.PendingResult' согласно декларации.
Это произошло после слияния. Мой коллега обновил библиотеку с 10.0.1
до 10.2.1
. Чистая сборка не помогла.
Из-за ограничений по времени я вернулся к более старой версии, и всё заработало.
Правка: Поскольку люди продолжают голосовать за этот ответ, хочу отметить, что он был написан в 2017 году. Я не уверен, актуален ли он до сих пор... Надеюсь, он все еще будет полезен для кого-то из вас...
В моем случае я просто отключил опцию "Instant Run" в настройках "Сборка, выполнение, развертывание".
Для этого:
- Перейдите в "Файл" > "Настройки" > "Сборка, выполнение, развертывание" > "Instant Run"
- Снимите отметку с поля "Включить Instant Run..." и нажмите кнопку "OK"
Ошибка «Необходимо переопределить метод суперкласса» после импорта проекта в Eclipse
Использование контекста в фрагменте
Как заставить Android-устройство вибрировать с разной частотой?
Room - Директория экспорта схемы не указана аннотационному процессору, не удается экспортировать схему
Как сгенерировать уникальный хеш-код для строкового ввода в Android?