NoClassDefFoundError: android.support.v7.internal.view.menu.MenuBuilder

Существует проблема с библиотекой Android appcompat v7 на устройствах Samsung под управлением Android 4.2. Я продолжаю получать сбои со следующей трассировкой стека в моей консоли разработчика:

java.lang.NoClassDefFoundError: android.support.v7.internal.view.menu.MenuBuilder
    at android.support.v7.widget.PopupMenu.<init>(PopupMenu.java:66)
    at com.[my-package-name].CustomActivity$5.onClick(CustomActivity.java:215)
    at android.view.View.performClick(View.java:4222)
    at android.view.View$PerformClick.run(View.java:17620)
    at android.os.Handler.handleCallback(Handler.java:800)
    at android.os.Handler.dispatchMessage(Handler.java:100)
    at android.os.Looper.loop(Looper.java:194)
    at android.app.ActivityThread.main(ActivityThread.java:5391)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:525)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
    at dalvik.system.NativeStart.main(Native Method)

Это строка 215 CustomActivity.java:

PopupMenu popup = new PopupMenu(CustomActivity.this, mImageViewMenu);

Аварии происходят из массива устройств, но всегда Samsung и всегда Android 4.2.

Быстрый веб-поиск заставляет меня поверить, что у многих людей такая же проблема, некоторые из шагов, которые я попытался решить, это:

  • Проверьте свойства проекта Android, убедитесь, что библиотека appcompat добавлена ​​правильно.
  • Проверьте свойства заказа и экспорта проекта Java Build Path, убедитесь, что Android Dependencies и частные библиотеки Android отмечены.
  • Подтвердить, что класс включен в библиотеку (android.support.v7.internal.view.menu.MenuBuilder).
  • Подтвердить R.java находится в каталоге gen для android.support.v7.appcompat.
  • Подтвердить, что тема AppCompat включена в действие Manifest.xml.
  • Очистить и перестроить проект.

Несмотря на эти шаги, и несмотря на то, что он работает на всех других устройствах и версиях Android, отчеты о сбоях все еще проходят.

Ответ 1

EDIT:

Решение, которое сработало для меня, было (с помощью Proguard), чтобы заменить это:

-keep class android.support.v4.** { *; } 
-keep interface android.support.v4.** { *; }

-keep class android.support.v7.** { *; }
-keep interface android.support.v7.** { *; }

с этим:

# Allow obfuscation of android.support.v7.internal.view.menu.**
# to avoid problem on Samsung 4.2.2 devices with appcompat v21
# see https://code.google.com/p/android/issues/detail?id=78377
-keep class !android.support.v7.internal.view.menu.**,android.support.** {*;}

Кредит переходит в группу google, # 138.

Старый ответ (Временное обходное решение): Это происходит в проекте, где я использую spinner в ActionBar. Мое решение состояло в том, чтобы проверить эти условия и изменить поток приложений:

public static boolean isSamsung_4_2_2() {
    String deviceMan = Build.MANUFACTURER;
    String deviceRel = Build.VERSION.RELEASE;
    return "samsung".equalsIgnoreCase(deviceMan) && deviceRel.startsWith("4.2.2");
}

Затем в операции onCreate метод:

if (isSamsung_4_2_2()) {
    setContentView(R.layout.activity_main_no_toolbar);
} else {
    setContentView(R.layout.activity_main);
}

Как уже отмечалось, это не окончательное решение, это просто способ позволить пользователям иметь доступ к ограниченной функциональности, в то время как найдено более постоянное решение.

Ответ 2

Как # 150 из групп google сказал

Потому что осторожно с классом -keep! Android.support.v7.internal.view.menu. **. Существует ряд классы, на которые ссылаются ресурсы appcompat.

Лучшее решение вместо этого добавляет следующие строки:

-keep class !android.support.v7.internal.view.menu.*MenuBuilder*, android.support.v7.** { *; }
-keep interface android.support.v7.** { *; }

Ответ 3

На каком устройстве вы столкнулись с этой проблемой? (Samsung/HTC и т.д.)

Если это Samsung,

В различных телефонах Samsung включены более старые версии библиотеки поддержки Android в рамках framework или classpath. Если вы используете новую библиотеку поддержки материалов, вы увидите эту ошибку на этих устройствах Samsung:

java.lang.NoClassDefFoundError: android.support.v7.internal.view.menu.MenuBuilder

Чтобы исправить это, вы должны переименовать этот класс. Самый простой способ сделать это - запустить proguard. Если вы не хотите запутывать, вот 1 лайнер, чтобы переименовать только классы-нарушители:

-keep class !android.support.v7.internal.view.menu.**,** {*;}

Там проблема, связанная с этой проблемой, но поскольку это действительно ошибка Samsung, она никогда не будет исправлена ​​с их конца. Единственный способ исправить это на стороне Google/AOSP - это переименовать эти внутренние классы.

https://code.google.com/p/android/issues/detail?id=78377

Ответ 4

Эта проблема вернулась в AppCompat 23.1.1, где пакет .internal был удален из библиотеки jar.

Как указано в комментариях выше (кредиты для людей, которые предложили его там), теперь также должна измениться конфигурация proguard.

Чтобы снова ответить на приведенный выше ответ, попробуйте добавить эти строки в свои файлы proguard:

#FOR APPCOMPAT 23.1.1:
-keep class !android.support.v7.view.menu.*MenuBuilder*, android.support.v7.** { *; }
-keep interface android.support.v7.* { *; }

Вместо старого исправления:

#FOR OLDER APPCOMPAT VERSION:
-keep class !android.support.v7.internal.view.menu.*MenuBuilder, android.support.v7.** { ; }
-keep interface android.support.v7.* { *; }

Ответ 5

В соответствии с последними сообщениями отчета об ошибке это должно быть исправлено в новой версии библиотеки поддержки (24.0.0): https://code.google.com/p/android/issues/detail?id=78377#c374

Кто-то даже заявил, он исправил его.

Эта версия доступна с прошлого месяца, поэтому вы должны ее обновить.

Ответ 6

Да. Samsung уже знает о этой проблеме. Я могу предложить вам попробовать использовать ту же реализацию Popup из GitHub. Это не лучший способ, но будет работать.

Ответ 7

У меня была такая же проблема с этим классом MenuBuilder, который не найден в режиме отладки USB. Я решил эту проблему, просто установив minifyEnabled в true как в блоке buildTypes buildTypes build.gradle, например:

buildTypes {

    debug {

        minifyEnabled true
    }

    release {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}

Я установил значение minifyEnabled в значение отлаживать, чтобы предотвратить сбой приложения через USB-отладку на живую трубку.

Ответ 8

Я включил proguard с свойствами proguard по умолчанию, предоставленными проектом eclipse, и проблема была исправлена ​​для меня. Исходя из некоторых комментариев здесь https://code.google.com/p/android/issues/detail?id=78377, некоторым людям, возможно, придется переупаковать, используя: -repackageclasses "android.support.v7"

Ответ 9

У меня такая же ошибка при попытке запустить приложение "Hello World" на моем планшете Samsung Galaxy Tab 3 через Android Studio. Приложение, похоже, запустится, а затем оно мгновенно сработает и эта ошибка появится на консоли в Android Studio. Я сделал обновление системы на планшете, и теперь я могу запустить приложение Hello World, и я больше не получаю ошибку. Надеюсь, это поможет кому-то решить их проблему.

Примечание. Обновление системы, которое я выполнил на планшете, не обновляло версию ОС Android, потому что она все еще говорит, что версия 4.2.2.

Ответ 10

Измените версию Compile Sdk вашего проекта на "API 18: (JellyBean)"

По умолчанию установлено значение "Lollipop

ШАГОВ

  • Щелкните правой кнопкой мыши на своем проекте и выберите "Открыть настройки модуля" (или нажмите F4)
  • На вкладке свойств Скомпилированная версия Sdk