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




eclipse appcompat (7)

Há um problema com a biblioteca Android appcompat v7 em dispositivos Samsung que executam o Android 4.2. Continuo a obter falhas com o seguinte rastreio de pilha na minha Consola do Programador:

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)

Esta é a linha 215 do CustomActivity.java:

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

As falhas vêm de uma variedade de dispositivos, mas sempre da Samsung e sempre do Android 4.2.

Uma rápida pesquisa na web me leva a acreditar que muitas pessoas têm o mesmo problema, algumas das etapas que tentei resolver o problema são:

  • Verifique as propriedades do projeto Android, verifique se a biblioteca appcompat foi adicionada corretamente.
  • Verifique as propriedades do projeto Java Build Path Order e Export, verifique se as Dependências do Android e as Bibliotecas Privadas do Android estão marcadas.
  • Confirme se a classe está incluída na biblioteca (android.support.v7.internal.view.menu.MenuBuilder).
  • Confirme se R.java está localizado no diretório gen para android.support.v7.appcompat.
  • Confirme se o tema AppCompat está incluído na atividade Manifest.xml.
  • Limpar e reconstruir o projeto.

Apesar dessas etapas, e apesar de estar funcionando em todos os outros dispositivos e nas versões do Android, os relatórios de falhas ainda são exibidos.


Alterar a versão do Sdk de compilação do seu projeto para "API 18: (JellyBean)"

O padrão é definido como "Lollipop

PASSOS

  1. Clique com o botão direito no seu projeto e selecione Open Module Settings (ou pressione F4)
  2. Na aba de propriedades Compiled Sdk Version

Como # 150 do Google grupos disseram

Porque cuidado com a classe -keep! Android.support.v7.internal.view.menu. **. Há um número de classes lá que são referenciadas dos recursos do appcompat.

A melhor solução é adicionar as seguintes linhas:

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

EDITAR:

A solução que funcionou para mim foi (usando o Proguard) para substituir isso:

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

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

com isso:

# 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.** {*;}

O crédito vai para o grupo do google # 138 .

Resposta antiga (solução temporária): acontece em um projeto em que uso um controle giratório no ActionBar. Minha solução foi verificar essas condições e alterar o fluxo do aplicativo:

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");
}

Então, no método onCreate da atividade:

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

Como apontado, esta não é uma solução definitiva, é apenas uma forma de permitir que os usuários tenham acesso a funcionalidades limitadas, enquanto uma solução mais permanente é encontrada.


Em qual dispositivo você está enfrentando esse problema? (Samsung / HTC etc.)

Se é Samsung,

Vários telefones Samsung estão incluídas versões mais antigas da biblioteca de suporte do Android no framework ou classpath. Se você usar a nova biblioteca de suporte a material, verá essa falha nesses dispositivos da Samsung:

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

Para corrigir isso, você deve renomear essa classe. A maneira mais fácil de fazer isso é executando o proguard. Se você não quer ofuscar, aqui está um 1 liner para renomear apenas as classes ofensivas:

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

Há um problema em rastrear esse problema, mas como é um erro da Samsung, ele nunca será corrigido. A única maneira de corrigi-lo no lado do Google / AOSP é renomear essas classes internas.

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


Eu estava tendo o mesmo problema desta classe MenuBuilder não encontrada no modo de depuração USB. Eu resolvi esse problema simplesmente definindo o minifyEnabled como true no bloco buildTypes release e debug do build.gradle . como isso:

buildTypes {

    debug {

        minifyEnabled true
    }

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

Eu defino o minifyEnabled como true no tipo de depuração para evitar que o aplicativo trave por meio de depuração USB em um aparelho ativo .


Eu habilitei o proguard com as propriedades padrão do programa fornecidas com um projeto eclipse e o problema foi corrigido para mim. Com base em alguns comentários aqui https://code.google.com/p/android/issues/detail?id=78377 , algumas pessoas podem precisar reempacotar usando: -repackageclasses "android.support.v7"


Sim. A Samsung já conhece this problema. Eu posso sugerir que você tente usar a mesma implementação do Popup do GitHub . Não é o melhor caminho, mas serão obras.