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에서 이런 일이 발생하는 것을 보았습니다. 따라서 실패한 삼성 ROM과 동일한 접근 방식 또는 동일한 ROM을 사용하는 것처럼 보입니다.
윌리엄

Google과 Samsung은이 거대한 문제를 해결하는 데 도움이되지 않으므로 Proguard와 관련이없는 솔루션 (다른 문제가 발생 함)을 생각할 수 있습니까?
점검표

Google은 라이브러리간에 이름 충돌을 일으키는 추가 수정을 한 것으로 보이는 삼성이기 때문에 구글은 그것에 대해 아무것도하지 않을 것입니다. Proguard는 충돌을 피합니다. Android Issue Tracker 포럼 에서도 더 나은 솔루션을 보지 못했습니다 .
매트 K

파키스탄에서도 QMobile A290을 추가 할 수 있습니다.
sstn

2
같은 문제 [QMobile X30-Android 4.4.2]
shanraisshan 2016 년

답변:


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
다른 사람이이 답변을 확인할 수 있습니까? 삼성에 액세스 할 수 없으며 작업중 인 앱이 더 이상 활성화되어 있지 않아 테스트 할 수 없습니다.
Matt K

3
@JaredBurrows 라이브러리를 제거하지 마십시오, 당신은 당신이 android.support.v7.internal.view.menu를 제외하고 android.support에서 모든 것을 무시 수정과, 기본적으로 무시하는 난독에게
의 Unify

2
저는 최근 몇 달 동안이 문제 보고서의 솔루션을 사용하고 있으며 최신 지원 라이브러리 및 SDK 23으로 업데이트 한 후 갑자기 모든 문제가 발생했습니다.java.lang.NoClassDefFoundError: android.support.v7.internal.view.menu.i
crashlytics

3
II를 AppCompat v23으로 업그레이드 할 때 문제가 앱에서 반환되었습니다. AppCompat v.23.1.1 jar 파일을 분석 한 결과 v7에서 "내부"디렉토리가 제거 된 것을 확인 했으므로 Proguard 명령 줄이 다음과 같아야합니다. [-keep class! android.support.v7.view. menu. **, android.support. ** {*;}] 그래도 문제가 발생한 실제 장치의 테스트에서 확인을받지 못했습니다. 그러한 장치를 가진 사람이 이것을 테스트 할 수 있습니까? 아니면 '내부'디렉토리를 제거하는 것이 실제로 문제의 해결책이며 더 이상 Proguard 클래스 이름 바꾸기를 망칠 필요가 없습니까?
gregko

7
이것을 보호 설정에 추가하면 문제가 해결됩니다. APPCOMPAT 23.1.1 : -keep class! android.support.v7.view.menu. * MenuBuilder *, android.support.v7. ** { ; }-인터페이스 android.support.v7. * 유지 { ; } 이전 APPCOMPAT 버전의 경우 : -keep class! android.support.v7.internal.view.menu. * MenuBuilder , android.support.v7. ** { ; }-인터페이스 android.support.v7. * 유지 * * *; }
Andrea Bellitto

26

마찬가지로 구글 홈페이지에서 # 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.** { *; }

내 테스트에서 생성 된 proguard 매핑 파일을 검토 한 결과, 제안 된 proguard 구성은 SubMenuBuilder를 난독 화하지만 MenuBuilder 클래스 이름을 난독 처리하지 않습니다.
Andy Dennie

3
@William 누군가가 그것을 삭제했습니다. 이유를 모르겠습니다. 어쨌든, 여기 내 해결책이 있습니다 : -keep class !android.support.v7.internal.view.menu.* implements android.support.v4.internal.view.SupportMenu, android.support.v7.** {*;}
Andy Dennie

3
이것은 app compat v23 으로 -keep class !android.support.v7.internal.view.menu.**,** {*;} 더 이상 작동하지 않는 곳에서 저에게 효과적 이었습니다 .
Quentin Klein

1
-keep class !android.support.v7.internal.view.menu.*MenuBuilder*, android.support.v7.** { *; } -keep interface android.support.v7.** { *; }답변으로 :)
Quentin Klein

2
23.1.1 지원 라이브러리에서 내부 패키지 경로가 수정되었으므로 이제 올바른 proguard 설정은 다음과 같습니다. -keep class! android.support.v7.view.menu. * MenuBuilder *, android.support.v7. ** { ; }-인터페이스 android.support.v7. * 유지 * * *; }
Andrea Bellitto

23

어떤 장치에서이 문제가 발생합니까? (삼성 / HTC 등)

삼성이라면

다양한 삼성 전화는 프레임 워크 또는 클래스 경로에 이전 버전의 Android 지원 라이브러리가 포함되어 있습니다. 새로운 재료 지원 라이브러리를 사용하는 경우 해당 Samsung 장치에서이 충돌이 나타납니다.

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

이 문제를 해결하려면 해당 클래스의 이름을 바꿔야합니다. 가장 쉬운 방법은 proguard를 실행하는 것입니다. 난독 화하지 않으려는 경우 문제가되는 클래스의 이름을 바꾸는 1 개의 라이너가 있습니다.

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

이 문제를 추적하는 데 문제가 있지만 실제로는 삼성 버그이므로 절대로 해결되지 않습니다. Google / AOSP 측에서 수정하는 유일한 방법은 이러한 내부 클래스의 이름을 바꾸는 것입니다.

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


v4 지원을 위해 proguard를 사용합니까?
Jared Burrows

@JaredBurrows 지원 v7을 시도했습니다. 그러나 v4의 경우에도 작동합니다.
Ganesh AB-Android

2
@ Android007 : 실제로 작동하는 해결 방법을 지적 해 주셔서 감사합니다. 그러나 누락 된 "android.support.v7.internal.view.menu.MenuBuilder"클래스를 사용할 수 있기 때문에 이전 Android 지원 라이브러리를 bootclasspath에 포함하는 결함 ROM이이 예외를 발생시키는 이유를 아무도 설명 할 수없는 것 같습니다. 이 문제로 고통받는 응용 프로그램의 APK DEX 코드. 안드로이드 런타임이 bootclasspath jar / dex 파일에서 가져온 클래스와 응용 프로그램을로드하는 방법을 설명하는 포인터가 있습니까? 아니면 정확한 설명이 필요하세요?
Édouard Mercier

@ ÉdouardMercier 늦게 답변해서 죄송합니다. 현재 귀하의 질문에 대한 답변이 없지만 곧 다시 연락 드리겠습니다. :)
Ganesh AB-Android

모든 프로그래머로서 @ Android007에게 고마워요. 마술은별로 좋아하지 않습니다.) 힌트 : 내장 된 bootclasspath에 "sealed".jar / .dex가 포함되어 있을까요?
Édouard Mercier 2019

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으로 업그레이드하고 해결 방법으로 사용한 난독 처리를 제거했으며 이전에 충돌이 발생한 삼성 테스트 장치에서 충돌이 발생하지 않았습니다.
Mark McClelland

4

예. 삼성 전자는 이미 알고 문제. GitHub 에서 동일한 Popup 구현을 사용하도록 제안 할 수 있습니다 . 가장 좋은 방법은 아니지만 작품이 될 것입니다.


1
예, 나는 삼성 포럼에서 그것을 보았지만 그들의 대표자 또는 지원자가 대답하지 않았기 때문에 그들이 관심이있는 것처럼 보이지 않습니다.
Matt K

4

USB 디버깅 모드 에서이 MenuBuilder 클래스와 동일한 문제가 발생했습니다. 나는 간단하게 설정하여이 문제를 해결 minifyEnabled을사실 모두 릴리스 및 디버그에 buildTypes 의 블록 build.gradle . 이처럼 :

buildTypes {

    debug {

        minifyEnabled true
    }

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

USB 디버깅을 통해 라이브 핸드셋으로 앱이 충돌하지 않도록 디버그 유형 에서 minifyEnabled 를 true로 설정했습니다 .


0

이클립스 프로젝트와 함께 제공되는 기본 proguard 속성으로 proguard를 활성화했으며 문제가 해결되었습니다. https://code.google.com/p/android/issues/detail?id=78377 에 대한 일부 의견을 바탕으로 일부 사람들은 다음을 사용하여 다시 포장해야 할 수도 있습니다. -repackageclasses "android.support.v7"


포럼에서 대부분의 사람들에게 효과가없는 것 같습니다. appcompat-20으로 돌아가는 것이 더 안정적인 옵션 인 것 같습니다.
Matt K

이것은 가정 지원 v23.1.1에서 해결되었습니다
팀 Malseed을

0

Android Studio를 통해 Samsung Galaxy Tab 3 태블릿에서 'Hello World'앱을 실행하려고 할 때도 같은 오류가 발생했습니다. 앱이 시작된 다음 즉시 충돌하고 해당 오류가 Android Studio의 콘솔에 표시됩니다. 태블릿에서 시스템 업데이트를했는데 이제 'Hello World'앱을 실행할 수 있으며 더 이상 오류가 발생하지 않습니다. 이것이 누군가가 문제를 해결하는 데 도움이되기를 바랍니다.

참고 : 태블릿에서 수행 한 시스템 업데이트는 여전히 버전이 4.2.2라고 표시되어 Android OS 버전을 업데이트하지 않았습니다.


-4

프로젝트의 컴파일 SDK 버전을 "API 18 : (JellyBean)"으로 변경하십시오.

기본 설정은 "롤리팝

단계

  1. 프로젝트를 마우스 오른쪽 단추로 클릭하고 모듈 설정 열기를 선택하십시오 (또는 F4를 누르십시오).
  2. 속성 탭에서 컴파일 된 SDK 버전
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.