appcompat-v7 v21.0.0 powodując awarię na urządzeniach Samsung z systemem Android v4.2.2

79

Właśnie zmieniliśmy naszą aplikację, aby korzystała z appcompat-v7 supportbiblioteki, aby skorzystać z paska akcji wsparcia i obsługiwać motywy Material. Używając v21.0.0 of appcompat-v7(i v21.0.0 of support-v4), teraz widzimy awarie w Google Playi Crashlytics tylko z urządzeń Samsung runningAndroid v4.2.2 . Here is the stack trace from Google Play and the app appears to crash as soon as theactionbar) jest wyświetlany i / lub unieważniany.

java.lang.NoClassDefFoundError: android.support.v7.internal.view.menu.MenuBuilder
at android.support.v7.app.ActionBarActivityDelegateBase.initializePanelMenu(ActionBarActivityDelegateBase.java:991)
at android.support.v7.app.ActionBarActivityDelegateBase.preparePanel(ActionBarActivityDelegateBase.java:1041)
at android.support.v7.app.ActionBarActivityDelegateBase.doInvalidatePanelMenu(ActionBarActivityDelegateBase.java:1259)
at android.support.v7.app.ActionBarActivityDelegateBase.access$100(ActionBarActivityDelegateBase.java:80)
at android.support.v7.app.ActionBarActivityDelegateBase$1.run(ActionBarActivityDelegateBase.java:116)
at android.os.Handler.handleCallback(Handler.java:725)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:176)
at android.app.ActivityThread.main(ActivityThread.java:5299)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
at dalvik.system.NativeStart.main(Native Method)

Inne urządzenia i emulatory działające w wersji 4.2.2 nie wykazują tego zachowania. Rozumiem, że wiele aplikacji Google używa już tej nowej wersji programu appcompatdo wyświetlania paska akcji. Jeśli te aplikacje nie zgłaszają awarii na tych urządzeniach, warto wiedzieć, w jaki sposób można tego uniknąć / naprawić.

Zgłosiłem to jako błąd do Google, ale został zamknięty z tego powodu, że jest to problem programistyczny. Chociaż zgadzam się, że może tak być, zastanawiam się, czy / jak ktokolwiek może obecnie używać appcompat-v7 v21.0.0i nie ma awarii Samsung 4.2.2 devices.

Aktualizacja: wygląda na to, że Google przynajmniej rozważa możliwe obejścia tego problemu. Zobacz to, aby uzyskać szczegółowe informacje.

Erik Pedersen
źródło
Może to być powiązany problem, ale wydaje się, że jest to nieco inny wyjątek. Jedno z niedawnych rozwiązań zamieszczonych w drugim pytaniu dotyczy posiadania pokrętła na pasku akcji i nie mam takiej sytuacji. Używam tylko pozycji menu.
Erik Pedersen
Ja też mam ten problem. Aplikacja jest w produkcji i otrzymuje awarie z Samsunga z wersją 4.2.2. urządzenia
Martin Vandzura
1
Nie mam też pokrętła na moim pasku akcji i otrzymuję go z urządzeń innych niż Samsung z systemem Android 4.2.2: Qmobile I9 i Wiko (nieznany model).
Jürgen 'Kashban' Wahlmann
1
@Devashish: Rozwiązanie proguard w drugiej odpowiedzi zadziałało. Testowałem na urządzeniu Samsung dotkniętym przez appthwack.com i po zastosowaniu konfiguracji proguard nie dostałem więcej błędów.
Jürgen 'Kashban' Wahlmann

Odpowiedzi:

15

Odpowiednie rozwiązanie znalazłem tutaj: https://stackoverflow.com/a/26641388/1266123

Używając

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

zamiast

-keep class android.support.v7.** {*;}
robUx4
źródło
1
Myślę, że możesz zaoszczędzić więcej miejsca, używając „-keepnames” zamiast „-keep”.
Justin
Jak wspomniano w dyskusji z code.google.com/p/android/issues/detail?id=78377 , użycie tego konkretnego rozwiązania może powodować problemy z powodu odwołań do zasobów w bibliotece appcompat. Jednak to działało w przypadku naszej konkretnej aplikacji, więc oznaczam tę odpowiedź jako zaakceptowaną.
Erik Pedersen
gdzie mam napisać ten wiersz?
Bugs Happen
@BugsHappen, to trafi do twojego pliku kompilacji Gradle. Możesz przeczytać więcej o ProGuard tutaj: developer.android.com/tools/help/proguard.html
Dick Lucas
7

Jak # 150 z https://code.google.com/p/android/issues/detail?id=78377 powiedział

Ponieważ uważaj na -keep class! Android.support.v7.internal.view.menu. **. Istnieje tam wiele klas, do których istnieją odwołania z zasobów appcompat.

Lepszym rozwiązaniem jest dodanie następujących linii:

-keep class !android.support.v7.internal.view.menu.MenuBuilder, !android.support.v7.internal.view.menu.SubMenuBuilder, android.support.v7.** { *; }
-keep interface android.support.v7.** { *; }
Pongpat
źródło
W moich testach, w oparciu o przegląd wygenerowanego pliku mapowania proguard, ta sugerowana konfiguracja proguard nie powoduje zaciemnienia nazwy klasy MenuBuilder, chociaż zaciemnia SubMenuBuilder
Andy Dennie
Domyśliłam się; zobacz moją odpowiedź.
Andy Dennie
hej Andy, mam ten sam problem, MenuBuilder nie jest zaciemnione, ale inni tak, powiedz mi, jak go rozwiązałeś? dzięki
Qing
6

Ponieważ Appcompat 23.1.1na .internalopakowaniu w słoiku AppCompat został usunięty.

Zaktualizowana poprawka za pomocą proguard:

#FOR APPCOMPAT 23.1.1:
-keep class !android.support.v7.view.menu.*MenuBuilder*, android.support.v7.** { *; }
-keep interface android.support.v7.* { *; }
RWIL
źródło
1

Jeśli ktoś jest zainteresowany użyciem rozwiązania bez progaurdu.

Przeczytaj link, który wypróbowałem w jednej z moich aplikacji, który dał wyjątek na setSupportActionBar (pasek narzędzi) w onCreate ().

Jest to całkiem proste, wystarczy dodać blok próbny catch wokół połączenia

try {

 setSupportActionBar(toolbar);

} catch (Throwable t) {

 // WTF SAMSUNG!

}
Ravi
źródło
0

Napotkałem ten sam problem na Tecno P9, ale po użyciu narzędzi do kompilacji 24 i mojej biblioteki wsparcia użyłem 24.2.0, został naprawiony.

Ikechukwu Kalu
źródło
-2

Zmień wersję kompilacji Sdk projektu na „API 18: (JellyBean)”

Wartość domyślna to „Lollipop”

Jak dotąd rozwiązałem mój problem na Qmobile i9

KROKI

  1. Kliknij prawym przyciskiem myszy swój projekt i wybierz Otwórz ustawienia modułu (lub naciśnij F4)
  2. Na karcie właściwości Skompilowana wersja Sdk
Jazib Hasan
źródło
-3

Zastąp AppCompatActivity aktywnością

To mi pomogło.

Sachin Waghmare
źródło
Tania poprawka. Może używa AppCompat, ponieważ chce obsługiwać API <11 lub coś w tym stylu. To przełamie ten pomysł.
Sufian
Myślę, że może to być wystarczająco zły post, aby zostać odrzuconym, jeśli ktoś zgadza się z powodem podanym przez Sufiana. Ale nie tak źle, że można go usunąć.
Gangnus,
-3

Zastąpić

public class class_name extends AppCompatActivity
{

.........

}

Z

public class class_name extends Activity
{

.........

}

To mi pomogło.

Sachin Waghmare
źródło
Przestań duplikować odpowiedzi na to samo pytanie.
Sufian,