Wydałem wersję mojej aplikacji do Google Play i obudziłem się dziś rano z wieloma niezadowolonymi klientami. Najnowsza wersja aplikacji integruje obsługę monitora tętna Bluetooth o niskiej energii (BTLE).java.lang.NoClassDefFoundError na starszych wersjach Androida SDK
Aplikacja działa poprawnie na Androidzie 4.3 i 4.4, ale ulega awarii w wersjach 4.0, 4.1 i 4.2 z następującym błędem.
FATAL EXCEPTION: main
java.lang.NoClassDefFoundError: com.eiref.boatcoach.MainActivity
at com.eiref.boatcoach.WhatToDo.onClick(WhatToDo.java:274)
at android.view.View.performClick(View.java:4204)
at android.view.View$PerformClick.run(View.java:17355)
at android.os.Handler.handleCallback(Handler.java:725)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:152)
at android.app.ActivityThread.main(ActivityThread.java:5132)
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:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
at dalvik.system.NativeStart.main(Native Method)
Błąd występuje przy tworzeniu woli w prosty Onclick podobny do następującego ...
public void onClick(View v) {
Intent i = new Intent(this, MainActivity.class);
startActivity(i);
}
Po śpieszył się i kupowania 4.2 tablet więc mogę powtórzyć problem, doszedłem do wniosek, że ma to związek z tą nową wersją aplikacji obsługującej Bluetooth LE, która jest włączona w SDK 4.3 i nowszych. Jeśli usuniemy wszystkie odwołania do Bluetooth w MainActivity, to awarie znikną na urządzeniach 4.2 i wcześniejszych.
Zrozumiałam, czytając dokumentację, że można napisać aplikację, która zawiera funkcjonalność Bluetooth LE i działałaby na starszych urządzeniach, tak długo jak jeden był ostrożny, aby nie wykonywać kodu BTLE, używając czegoś podobnego do następującego ...
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) return;
BluetoothManager manager = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE);
mBluetoothAdapter = manager.getAdapter();
//etc.
Dlatego moja manifest.xml nie zaliczyć jak to uniemożliwić pobieranie do starszych urządzeń, a ja oczywiście chcą zachować jedną bazę kodu, jeśli to możliwe ...
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true" />
Pierwsze pytanie, czy moje założenie powyżej jest w stanie uwzględnić kod BTLE w pakietach SDK przed wersją 4.3? Jeśli nie, czy naprawdę muszę utworzyć dwie wersje aplikacji ... jedną dla osób używających 4.3 i późniejszych i jedną dla wszystkich innych?
Istnieje wiele postów StackOverflow o java.lang.NoClassDefFoundError i myślę, że przeczytałem większość istotnych. Wielu sugeruje, że sprawdzam ścieżkę budowania Java, aby upewnić się, że sprawdzane są prywatne biblioteki Androida i zależności Androida. Oni są. Niektórzy sugerują przeniesienie folderu gen przed folderem src, ale nie wydaje się to mieć znaczenia.
Chciałbym opublikować obraz ścieżki budowy Java Eclipse, ale ponieważ jest to mój pierwszy wpis, nie mam 10 punktów reputacji potrzebnych do wstawienia obrazu, więc oto kolejny wpis, którego przestrzegałem ... Android java.lang.NoClassDefFoundError
Tak, drugie pytanie, inne myśli o tym, co może być nie tak ze ścieżką budowania?
wielkie dzięki z góry.
Aktualizacja ... w jakiś sposób, zadając pytanie Mam wystarczającą liczbę punktów, aby opublikować obrazy ścieżki budowania Java. Jak wskazuje @Ashoke, uważam, że ma to coś wspólnego z niewłaściwą ścieżką budowania lub bibliotekami wsparcia.
Czy ten sam kod wewnątrz onClick uruchamiane na> = 4,3, czy też istnieje inna droga kod w zależności od wersji Androida? –
Zdecydowanie nie powinieneś potrzebować dwóch wersji aplikacji. Jeśli chodzi o znacznik use-feature, polecam, abyś to * uwzględnił, ale ustaw 'android: required =" false "'. Naprawdę nie sądzę, że to jest główny problem, ale i tak warto to zrobić. – kcoppock
@MichaelKrause - tak dokładnie ta sama ścieżka kodowa dla różnych wersji Androida. –