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


170

Android 4.2を実行しているSamsungデバイスのAndroid appcompat v7ライブラリに問題があります。開発者コンソールで次のスタックトレースを使用するとクラッシュし続けます。

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)

これは、CustomActivity.javaの215行目です。

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

クラッシュの原因はさまざまなデバイスですが、常にSamsung、Android 4.2が原因です。

簡単なウェブ検索で、多くの人が同じ問題を抱えていると思いました。問題を解決するために私が試みたステップのいくつかは次のとおりです。

  • Androidプロジェクトのプロパティを確認し、appcompatライブラリが適切に追加されていることを確認します。
  • Javaビルドパスの順序とエクスポートプロジェクトのプロパティを確認し、Android依存関係とAndroidプライベートライブラリがオンになっていることを確認します。
  • クラスがライブラリに含まれていることを確認します(android.support.v7.internal.view.menu.MenuBuilder)。
  • R.javaがandroid.support.v7.appcompatのgenディレクトリにあることを確認します。
  • AppCompatテーマがManifest.xmlアクティビティに含まれていることを確認します。
  • プロジェクトをクリーンアップして再構築します。

これらの手順にもかかわらず、それが他のすべてのデバイスとAndroidバージョンで機能しているにもかかわらず、クラッシュレポートは引き続き表示されます。


4
注:これは、パキスタン外のローエンド電話であるQMobile X25でも発生します。そのため、オイザーは故障したSamsung ROMと同じアプローチまたは同じROMを使用しているようです。
ウィリアム

GoogleとSamsungの両方がこの巨大な問題の解決に役立たないので、誰もがProguardを含まない(他の問題を引き起こす)ソリューションを考えることができますか?
チェックリスト

ライブラリ間の名前の衝突を引き起こす追加の変更を加えたと思われるのはSamsungであるため、Googleはそれについて何もしません。プロガードは衝突を回避します。Android Issue Trackerフォーラムでもこれ以上の解決策を見たことがありません。
マットK

QMobile A290をパキスタンから追加することもできます。
sstn 2016年

2
同じ問題[QMobile X30-Android 4.4.2]
shanraisshan

回答:


100

編集:

私のために働いた解決策はこれを置き換える(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に送られます。

以前の回答(一時的な回避策):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
他の誰かがこの答えを確認できますか?Samsungにアクセスできず、作業していたアプリがアクティブでなくなったため、テストできません。
Matt K

3
あなたはandroid.support.v7.internal.view.menuを除くandroid.support下のすべてを無視修正して、あなただけのデフォルトでは、それを無視するようにProGuardのを教えて、ライブラリを削除しないでください@JaredBurrows
統一

2
私は今、数ヶ月のためにその問題のレポートからのソリューションを使用してきたとのすべての突然の最新のサポートライブラリにアップデートした後および23をSDK私はcrashlyticsにこの新しいレポートを取得開始しました:java.lang.NoClassDefFoundError: android.support.v7.internal.view.menu.i
casolorz

3
IIがAppCompat v23にアップグレードすると、問題がアプリに戻りました。AppCompat v.23.1.1 jarファイルを分析したところ、v7内の「内部」ディレクトリが削除されていることがわかりました。そのため、Proguardの命令行は次のようになります。[-keep class!android.support.v7.view。 menu。**、android.support。** {*;}]問題が発生した実際のデバイスでのテストからの確認がまだありません。そのようなデバイスを持っている人は誰でもこれをテストできますか?あるいは、「内部」ディレクトリの削除が実際の問題の修正であり、もうProguardクラスの名前変更をいじる必要はありませんか?
gregko 2015年

7
これをプロガード設定に追加すると、問題が解決します。APPCOMPAT 23.1.1の場合:-keep class!android.support.v7.view.menu。* MenuBuilder *、android.support.v7。** { ; } -keepインターフェースandroid.support.v7。* { ; }古いAPPCOMPATバージョンの場合:-keep class!android.support.v7.internal.view.menu。* MenuBuilder、android.support.v7。** { ; } -keepインターフェースandroid.support.v7。* {*; }
Andrea Bellitto

26

Googleグループから#150は言いました

-keep class!android.support.v7.internal.view.menu。**に注意してください。そこには、appcompatのリソースから参照されるいくつかのクラスがあります。

より良い解決策は、代わりに次の行を追加することです:

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

私のテストでは、生成されたプロガードマッピングファイルのレビューに基づいて、この提案されたプロガード構成は、MenuBuilderクラス名を難読化しませんが、SubMenuBuilderを難読化しません。
アンディデニー2015年

3
@William誰かがそれを削除しました。理由はわかりません。とにかく、これが私の解決策です: -keep class !android.support.v7.internal.view.menu.* implements android.support.v4.internal.view.SupportMenu, android.support.v7.** {*;}
Andy Dennie

3
これは、v23app compat-keep class !android.support.v7.internal.view.menu.**,** {*;} 動作しなくなった私にとってはうまくいきました
クエンティンクライン

1
-keep class !android.support.v7.internal.view.menu.*MenuBuilder*, android.support.v7.** { *; } -keep interface android.support.v7.** { *; }答えとして:)
Quentin Klein

2
23.1.1サポートライブラリでは、内部パッケージパスが変更されたため、正しいプロガード設定は次のようになります。} -keepインターフェースandroid.support.v7。* {*; }
Andrea Bellitto

23

この問題に直面しているデバイスはどれですか?(Samsung / HTCなど)

サムスンなら

さまざまなSamsung製の電話には、フレームワークまたはクラスパスに古いバージョンのAndroidサポートライブラリが含まれています。新しいマテリアルサポートライブラリを使用すると、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


Proguardをサポートv4に使用していますか?
Jared Burrows 2014

@JaredBurrowsサポートv7を試してみました。しかし、v4でも機能します。
Ganesh AB-Android

2
@ Android007:実際に機能する回避策を指摘していただきありがとうございます。ただし、「android.support.v7.internal.view.menu.MenuBuilder」クラスがで利用できるため、古いAndroidサポートライブラリがbootclasspathに埋め込まれている障害のあるROMがこの例外を引き起こす理由を説明できないようです。この問題に苦しむアプリケーションのapk DEXコード。Androidランタイムがbootclasspath jar / dexファイルから取得したクラスとアプリケーションのクラスをどのようにロードするかを説明するポインタがありますか?または正確な説明をお願いします。
エドゥアールメルシエ2014

@ÉdouardMercier返信が遅くなってすみません。現在、質問に対する回答はありませんが、まもなくご連絡いたします。:)
Ganesh AB-Android

@ Android007に感謝します。プログラマーとして、私は魔術はあまり好きではありません。
エドゥアールメルシエ

15

この問題はAppCompat 23.1.1.internalパッケージがライブラリjarから削除された場所に戻りました。

上記のコメントで提案されているように(そこで提案した人々へのクレジット)、今度はプロガード構成も変更する必要があります。

上記の提案された答えが再び機能するようにするには、次の行を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.* { *; }

!android.support.v7.view.menu.**SubMenuBuilderのような他のクラスのために安全です
JaredBanyard

12

バグレポートの最後の投稿によると、これはサポートライブラリの新しいバージョン(24.0.0)で修正する必要がありますhttps ://code.google.com/p/android/issues/detail?id=78377 #c374

誰かそれを修正したとさえ主張した。

このバージョンは先月から利用できるため、更新する必要があります。


私たちのテストでは、24.0.0が問題を修正することが確認されています。サポートライブラリを24.0.0(アルファではない)にアップグレードし、回避策として使用していた難読化を削除し、以前にクラッシュを確認したSamsungテストデバイスでクラッシュを確認しませんでした。
マークマクレランド

4

はい。Samsungはすでにこの問題を認識してます。GitHubのPopupの同じ実装を使用してみることをお勧めします。それは最善の方法ではありませんが、動作します。


1
はい、私はサムスンのフォーラムでそれを見ましたが、彼らの代表者やサポートのいずれも返答していないので、彼らは興味がないようです。
マットK 14

4

USBデバッグモードで見つからないこのMenuBuilderクラスの同じ問題がありました。build.gradleの releaseおよびdebug buildTypesブロックの両方でminifyEnabledtrueに設定するだけでこの問題を解決しました。このような:

buildTypes {

    debug {

        minifyEnabled true
    }

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

デバッグタイプでminifyEnabledをtrue に設定して、アプリがUSBデバッグを介してライブハンドセットにクラッシュするのを防ぎます。


0

日食プロジェクトで提供されるデフォルトのプロガードプロパティでプロガードを有効にしたところ、問題は修正されました。ここhttps://code.google.com/p/android/issues/detail?id=78377のコメントに基づいて、一部の人々は-repackageclasses "android.support.v7"を使用して再パッケージ化する必要があるかもしれません


フォーラムのほとんどの人にとってそれはうまくいっていないようです。appcompat-20に戻る方が信頼性の高いオプションのようです。
Matt K

これはサポートv23.1.1で解決されたと思われます
Tim Malseed 2015年

0

Android Studioを介してSamsung Galaxy Tab 3タブレットで「Hello World」アプリを実行しようとすると、同じエラーが発生しました。アプリが起動したように見えてすぐにクラッシュし、そのエラーはAndroid Studioのコンソールに表示されます。タブレットでシステムアップデートを実行したところ、「Hello World」アプリを実行でき、エラーが発生しなくなりました。これが誰かが問題を解決するのに役立つことを願っています。

注:タブレットで実行したシステムアップデートでは、Android OSのバージョンがまだ4.2.2と表示されているため、Android OSのバージョンは更新されませんでした。


-4

プロジェクトのコンパイルSDKバージョンを「API 18:(JellyBean)」に変更します

デフォルトは「ロリポップ

手順

  1. プロジェクトを右クリックし、[Open Module Settings]を選択します(またはF4を押します)。
  2. プロパティタブでコンパイルされたSDKバージョン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.