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


170

Android 4.2 çalıştıran Samsung cihazlarda Android appcompat v7 kütüphanesinde bir sorun var. Geliştirici Konsolumda aşağıdaki yığın izlemesiyle kilitlenmeye devam ediyorum:

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)

Bu, CustomActivity.java'nın 215. satırıdır:

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

Çökmeler bir dizi cihazdan geliyor, ancak her zaman Samsung ve her zaman Android 4.2.

Hızlı bir web araması, birçok insanın aynı soruna sahip olduğuna inanmamı sağlıyor, sorunu çözmeye çalıştığım adımlardan bazıları şunlardır:

  • Android proje özelliklerini kontrol edin, appcompat kütüphanesinin doğru bir şekilde eklendiğinden emin olun.
  • Java Oluşturma Yolu Siparişi ve Dışa Aktarma proje özelliklerini kontrol edin, Android Bağımlılıkları ve Android Özel Kütüphanelerinin işaretli olduğundan emin olun.
  • Sınıfın kütüphanede bulunduğunu onaylayın (android.support.v7.internal.view.menu.MenuBuilder).
  • R.java'nın android.support.v7.appcompat için gen dizininde olduğunu onaylayın.
  • AppCompat temasının Manifest.xml etkinliğine dahil edildiğini doğrulayın.
  • Projeyi temizleyin ve yeniden oluşturun.

Bu adımlara rağmen ve diğer tüm cihazlarda ve Android sürümlerinde çalışmasına rağmen, kilitlenme raporları hala geliyor.


4
Not: Bunun Pakistan'dan düşük kaliteli bir telefon olan QMobile X25'te de olduğunu gördüm. Yani oymerler başarısız Samsung ROM ile aynı yaklaşımı veya ROM'u almış gibi görünüyor.
William

Hem Google hem de Samsung bu BÜYÜK sorunun çözümünde yardımcı olmadığından, Proguard'ı içermeyen bir çözüm düşünebilir (diğer sorunları gündeme getirir)?
kontrol listesi

Samsung, kütüphaneler arasında bir isim çarpışmasına neden olan ek değişiklikler yapmış gibi görünen Samsung olduğu için bu konuda hiçbir şey yapmayacak. Proguard çarpışmayı önler. Android Issue Tracker forumunda da daha iyi bir çözüm görmedim .
Matt K

Pakistan'dan da bir QMobile A290 ekleyebilirim.
sstn

2
aynı konu [QMobile X30 - Android 4.4.2]
shanraisshan

Yanıtlar:


100

DÜZENLE:

Benim için işe yarayan çözüm, bunun yerine (Proguard Kullanımı) idi:

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

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

Bununla:

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

Kredi , # 138 google grubuna gidiyor .

Eski yanıt (Geçici Geçici Çözüm): ActionBar'da bir döndürücü kullandığım bir projede olur . Benim çözümüm bu koşulları kontrol etmek ve uygulama akışını değiştirmekti:

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

Ardından etkinliğin onCreate yönteminde:

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

Belirtildiği gibi, bu kesin bir çözüm değildir, daha kalıcı bir çözüm bulunurken kullanıcıların sınırlı işlevselliğe erişmesine izin vermenin bir yoludur.


2
Bu yanıtı başka biri doğrulayabilir mi? Bir Samsung'a erişimim yok ve üzerinde çalıştığım uygulama artık aktif değil, bu yüzden test edemiyorum.
Matt K

3
@JaredBurrows Kütüphaneyi çıkarmayın, sen sadece android.support.v7.internal.view.menu hariç android.support altında her şeyi görmezden düzeltme ile, varsayılan olarak görmezden ProGuard anlatmak
Birleştir'me

2
Aylardır bu sayı raporundan bir çözüm kullanıyorum ve en son destek kütüphanelerine güncelledikten sonra aniden ve sdk 23 crashlytics hakkında bu yeni raporu almaya başladım:java.lang.NoClassDefFoundError: android.support.v7.internal.view.menu.i
casolorz

3
II. AppCompat v23 sürümüne geçildiğinde sorun uygulamamda geri döndü. AppCompat v.23.1.1 jar dosyasını analiz ettim ve v7 içindeki "dahili" dizini kaldırdıklarını gördüm, bu yüzden Proguard komut satırının şimdi olması gerektiği anlaşılıyor: [-keep class! Android.support.v7.view. menu. **, android.support. ** {*;}] Hala sorunun yaşandığı gerçek bir cihazdaki testlerden onayım yok. Böyle bir cihazı olan herkes bunu test edebilir mi? Ya da belki 'dahili' dir kaldırılması aslında sorunun çözümü ve artık Proguard sınıfı yeniden adlandırma ile uğraşmak gerekmez?
gregko

7
Bunu koruma ayarlarınıza ekleyin, sorunu çözecektir: APPCOMPAT 23.1.1 İÇİN: -keep sınıfı! Android.support.v7.view.menu. * MenuBuilder *, android.support.v7. ** { ; } -birimli arayüz android.support.v7. * { ; } ESKİ APPCOMPAT VERSİYONU İÇİN: -sınıf tutun! Android.support.v7.internal.view.menu. * MenuBuilder , android.support.v7. ** { ; } -birimli arayüz android.support.v7. * {*; }
Andrea Bellitto

26

Şöyle hakkında gruplarından 150. bahsedilen

Çünkü -keep sınıfı ile dikkatli olun! Android.support.v7.internal.view.menu. **. Orada appcompat kaynaklarından referans verilen bir takım sınıflar vardır.

Daha iyi çözüm, aşağıdaki satırları eklemektir:

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

Testlerimde, oluşturulan koruma eşleme dosyasının gözden geçirilmesini temel alan bu önerilen koruma yapılandırması, SubMenuBuilder'ı gizlemesine rağmen MenuBuilder sınıf adını gizlemeyle sonuçlanmaz.
Andy Dennie

3
@William Birisi onu sildi, nedenini bilmiyorum. Her neyse, işte benim çözümüm: -keep class !android.support.v7.internal.view.menu.* implements android.support.v4.internal.view.SupportMenu, android.support.v7.** {*;}
Andy Dennie

3
Burası benim için çalıştı -keep class !android.support.v7.internal.view.menu.**,** {*;} ile artık çalışma değildi V23 ait uygulama COMPAT .
Quentin Klein

1
-keep class !android.support.v7.internal.view.menu.*MenuBuilder*, android.support.v7.** { *; } -keep interface android.support.v7.** { *; }cevap olarak :)
Quentin Klein

2
23.1.1 destek kütüphanesinde dahili paket yolları değiştirildi, şimdi doğru koruma ayarı: -keep class! android.support.v7.view.menu. * MenuBuilder *, android.support.v7. ** { ; } -birimli arayüz android.support.v7. * {*; }
Andrea Bellitto

23

Hangi cihazda bu sorunla karşı karşıyasınız? (Samsung / HTC vb.)

Samsung ise,

Çeşitli Samsung telefonlar, çerçeve veya sınıf yolunda android destek kütüphanesinin eski sürümlerini içerir. Yeni malzeme destek kitaplığını kullanırsanız, bu çökmeyi bu Samsung cihazlarında görürsünüz:

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

Bunu düzeltmek için bu sınıfı yeniden adlandırmanız gerekir. Bunu yapmanın en kolay yolu koruma çalıştırmaktır. Eğer gizlemek istemiyorsanız, sadece rahatsız edici sınıfları yeniden adlandırmak için 1 astar:

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

Bu sorunu takip eden bir sorun var, ancak gerçekten bir Samsung hatası olduğu için, onların sonunda asla düzeltilmeyecek. Google / AOSP tarafında düzeltmenin tek yolu bu dahili sınıfları yeniden adlandırmaktır.

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


Destek v4 için proguard kullanıyor musunuz?
Jared Burrows

@JaredBurrows Destek v7 için denedim. Ama v4 için de işe yarayacak.
Ganesh AB - Android

2
@ Android007: Gerçekten işe yarayan bu soruna işaret ettiğiniz için teşekkür ederiz. Ancak, hiç kimse eski Android Destek Kitaplığı'nı bootclasspath'ına gömen hatalı ROM'ların eksik "android.support.v7.internal.view.menu.MenuBuilder" sınıfında mevcut olduğundan bu özel duruma neden nedenini açıklayamıyor gibi görünüyor. apk Bu sorundan muzdarip uygulamanın DEX kodu. Android çalışma zamanının bootclasspath jar / dex dosyalarından ve uygulamalardan alınan sınıfları nasıl yüklediğini açıklayan herhangi bir işaretçi var mı? Veya herhangi bir kesin açıklama, lütfen?
Édouard Mercier

@ ÉdouardMercier Geç cevap verdiğim için üzgünüm. Şu anda sorunuzun cevabı yok ama yakında size geri döneceğim. :)
Ganesh AB - Android

Teşekkür ederim @ Android007, herhangi bir programcı olarak, çok büyücülük sevmiyorum;) Bir ipucu: gömülü bootclasspath davranışı açıklayacak "mühürlü" .jar / .dex içerir mi?
Édouard Mercier

15

Bu sorun AppCompat 23.1.1, .internalpaketin kitaplık kavanozundan kaldırıldığı yerde geri döndü .

Yukarıdaki yorumlarda önerildiği gibi (orada öneren kişilere verilen krediler), şimdi de koruma yapılandırmasının değişmesi gerekiyor.

Yukarıda önerilen cevabın tekrar çalışmasını sağlamak için koruma dosyalarınıza şu satırları eklemeyi deneyin:

#FOR APPCOMPAT 23.1.1:
-keep class !android.support.v7.view.menu.*MenuBuilder*, android.support.v7.** { *; }
-keep interface android.support.v7.* { *; }

Eski düzeltme yerine:

#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

Hata raporunun son gönderilerine göre, bu destek kütüphanesinin yeni sürümünde (24.0.0) düzeltilmelidir: https://code.google.com/p/android/issues/detail?id=78377 # c374

Birisi bunu düzelttiğini bile iddia etti .

Bu sürüm geçen aydan beri kullanılabilir , bu nedenle güncellemeniz gerekir.


Testlerimiz 24.0.0'ın sorunu düzelttiğini doğrulamaktadır. Destek kitaplığını 24.0.0'a (alfa değil) yükselttik, geçici çözüm olarak kullandığımız gizliliği kaldırdık ve daha önce çökmeyi gördüğümüz bir Samsung test cihazında çökme görmedik.
Mark McClelland

4

Evet. Samsung bu sorunu zaten biliyor . GitHub'dan aynı Popup uygulamasını kullanmaya çalışmanızı önerebilirim . En iyi yol değil, ama işe yarayacak.


1
Evet, Samsung forumunda gördüm, ancak temsilcilerinin veya desteklerinin hiçbiri yanıtlanmadığı için ilgileniyor gibi görünmüyor.
Matt K

4

Bu hata ayıklama modunda bulunamadı MenuBuilder sınıfı aynı sorunu yaşıyordum. Sadece ayarlayarak bu sorunu çözdü minifyEnabled için gerçek hem ayırma ve ayıklama içinde buildTypes blok build.gradle . bunun gibi:

buildTypes {

    debug {

        minifyEnabled true
    }

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

Uygulamanın USB hata ayıklaması yoluyla canlı bir ahizeye kilitlenmesini önlemek için hata ayıklama türünde minifyEnabled öğesini true olarak ayarladım .


0

Bir tutulma projesi ile sağlanan varsayılan koruma özellikleri ile korumayı etkinleştirdim ve sorun benim için düzeltildi. Buradaki bazı yorumlara dayanarak https://code.google.com/p/android/issues/detail?id=78377 , bazı kişilerin aşağıdakileri kullanarak yeniden paketlemeleri gerekebilir: -repackageclasses "android.support.v7"


Forumdaki çoğu kişi için işe yaramıyor gibi görünüyor. Appcompat-20'ye geri dönmek daha güvenilir bir seçenek gibi görünüyor.
Matt K

Bu sözde v23.1.1
Tim Malseed

0

Android Studio aracılığıyla Samsung Galaxy Tab 3 tabletimde 'Merhaba Dünya' uygulamasını çalıştırmaya çalışırken aynı hatayı aldım. Uygulama başlatılır ve anında kilitlenir ve bu hata Android Studio'daki konsolda gösterilir. Tablette bir sistem güncellemesi yaptım ve şimdi 'Merhaba Dünya' uygulamasını çalıştırabiliyorum ve artık hatayı almıyorum. Umarım bu, birinin sorununu çözmesine yardımcı olur.

Not: Tablette yaptığım sistem güncellemesi Android OS sürümünü güncellemedi, çünkü hala sürüm 4.2.2 olduğunu söylüyor.


-4

Projenizin Sdk Derleme Sürümü'nü "API 18: (JellyBean)" olarak değiştirin

Varsayılan "Lollipop" olarak ayarlanmıştır

ADIMLARI

  1. Projenize sağ tıklayın ve Modül Ayarlarını Aç'ı seçin (veya F4'e basın)
  2. Özellikler sekmesinde Derlenmiş Sdk Sürümü
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.