Android

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

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 и экспортируйте свойства проекта, убедитесь, что установлены флажки Android Dependencies и Android Private Libraries.

  • Подтвердите, что класс включен в библиотеку (android.support.v7.internal.view.menu.MenuBuilder).

  • Подтвердите R.java находится в каталоге gen для Android.support.v7.appcompat.

  • Подтвердите, что тема AppCompat включена в действие Manifest.xml .

  • Очистить и перестроить проект.

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

Переведено автоматически
Ответ 1

Редактировать:

Решение, которое сработало для меня, заключалось (с использованием 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.

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

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 groups сказано


Потому что осторожнее с -сохраняйте класс !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.* { *; }
java android