NoClassDefFoundError: android.support.design.internal.NavigationMenu на Android 4.2.2 (wiko)

Я пытаюсь использовать библиотеку Android Support Design (в версии 23.0.1) и класс NavigationMenu (я использую этот класс как тег XML в макете).

Когда я выполняю свое приложение на Samsung на Android 4.3 или на Nexus на Android 5.x или 6.0, все работает хорошо, но когда я запускаю приложение на Wiko Rainbow на Android 4.2.2, он вылетает со следующим исключение:

java.lang.RuntimeException: Unable to start activity ComponentInfo{applicationId/package.MainActivity}: android.view.InflateException: Binary XML file line #11: Error inflating class <unknown>
[...]
Caused by: android.view.InflateException: Binary XML file line #11: Error inflating class <unknown> 
Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Constructor.constructNative(Native Method)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:417)
        at android.view.LayoutInflater.createView(LayoutInflater.java:587)
[...]
Caused by: java.lang.NoClassDefFoundError: android.support.design.internal.NavigationMenu
        at android.support.design.widget.NavigationView.<init>(NavigationView.java:99)
        at android.support.design.widget.NavigationView.<init>(NavigationView.java:92)
        at java.lang.reflect.Constructor.constructNative(Native Method)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:417)
        at android.view.LayoutInflater.createView(LayoutInflater.java:587)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:687)
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
[...]

Эта ошибка заставляет меня задуматься о том, что у одного разработчика было несколько месяцев назад, используя библиотеку appcompat-v7 на некоторых телефонах Wiko и Samsung на Android 4.2.2.

Ошибка:

java.lang.NoClassDefFoundError:   android.support.v7.internal.view.menu.MenuBuilder
at android.support.v7.app.ActionBarActivityDelegateBase.initializePanelMenu(ActionBarActivityDelegateBase.java:914)
at android.support.v7.app.ActionBarActivityDelegateBase.preparePanel(ActionBarActivityDelegateBase.java:964)
at android.support.v7.app.ActionBarActivityDelegateBase.doInvalidatePanelMenu(ActionBarActivityDelegateBase.java:1182)
at android.support.v7.app.ActionBarActivityDelegateBase.access$100(ActionBarActivityDelegateBase.java:79)
at android.support.v7.app.ActionBarActivityDelegateBase$1.run(ActionBarActivityDelegateBase.java:118)
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)

Решение заключалось в использовании в проекте следующего файла proguard:

-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod

-dontobfuscate
-dontoptimize

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

Это решение было замечательным, потому что мне не нужно добавлять определенные правила (только некоторые строки -dontwarn) для других библиотек, которые я использую как Jackson, или для добавления определенных правил для компонентов Android.

Поскольку класс NavigationMenu наследует класс MenuBuilder, я думал, что мы можем изменить файл proguard, как это, чтобы исправить проблему:

-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod

-dontobfuscate
-dontoptimize

-keep class !android.support.design.internal.**, ** { *; }

К сожалению, он не работает... Поэтому я попробовал другое решение:

-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod

-dontobfuscate
-dontoptimize

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

Эти решения работают, но... На самом деле у меня больше нет исключения NoClassDefFoundError, но у меня есть другие исключения (которые встречаются на всех версиях Android), например:

  • некоторые отсутствующие конструкторы используют с отражением;
  • некоторые отсутствующие пустые конструкторы на объектах Джексона или на Fragment.

Итак, знаете ли вы решение, которое позволяет мне выполнить мое приложение на Wiko на Android 4.2.2, и в котором я не должен добавлять конкретные правила для каждой библиотеки, которую я использую или буду использовать в будущем?

Заранее благодарю вас за помощь!

Ответ 1

спасибо для Шимона Климашевского за помощь! Здесь файл proguard, который работает для меня:

-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod

-dontobfuscate
-dontoptimize
-repackageclasses ''

#Jackson
-dontwarn com.fasterxml.jackson.databind.**

#View Pager Indicator
-dontwarn com.viewpagerindicator.**

#Android
-keep class android.support.v4.app.** { *; }
-keep interface android.support.v4.app.** { *; }
-keep class android.support.v7.app.** { *; }
-keep interface android.support.v7.app.** { *; }
-keep class android.support.v13.app.** { *; }
-keep interface android.support.v13.app.** { *; }

#droid4me
-keep class com.smartnsoft.** { *; }

#my app
-keep class my.app.package.** { *; }

#Critercism
-keep public class com.crittercism.**
-keepclassmembers public class com.crittercism.* { *; }

Ответ 2

Я следую аналогичной теме и борюсь с поиском решения, но у меня нет устройства.

Основываясь на комментариях пользователей, я добавил следующее в конфигурацию proguard Тип сборки:

buildTypes {
    release {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-project.txt'
    }
}

ProGuard-project.txt

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

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

-keep class android.support.v13.app.** { *; }
-keep interface android.support.v13.app.** { *; }

Не могли бы вы попробовать следующую конфигурацию? У меня есть некоторые сомнения в этом решении, потому что когда у меня есть неработающие классы, у меня все еще был NavigationMenuView в том же пакете. Он не был перемещен из-за его отношений доступа к пакету. Так что может помочь добавить еще один флаг в конфигурацию proguard-project.txt, довольно рискованный:

-allowaccessmodification

Это может быть хорошим началом для исправления проблемы.

Итак, в вашем случае proguard-project должен выглядеть следующим образом:

-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod

-dontobfuscate
-dontoptimize
-allowaccessmodification
-repackageclasses ''
-keep class your.package.name.** { *; }
-keep class android.support.v4.app.** { *; }
-keep interface android.support.v4.app.** { *; }

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

-keep class android.support.v13.app.** { *; }
-keep interface android.support.v13.app.** { *; }

Ответ 3

Я собираюсь с этим. Я еще не пробовал, так как у меня нет каких-либо уязвимых устройств:

-keep class !android.support.design.internal.NavigationMenu,!android.support.design.internal.NavigationMenuPresenter,!android.support.design.internal.NavigationSubMenu

Это дополнение к этому правилу, которое помогает многим устройствам Samsung (см. http://goo.gl/ywG1c4):

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

Ответ 4

-

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

Ответ 5

Проверьте версию com.android.support:appcompat. Например, вместо com.android.support:appcompat-v7:23.1.1 попытайтесь использовать com.android.support:appcompat-v7:23.0.1