Z androidem nie mam dużo wspólnego. Mamy aplikację więc muszę ogarniać. Ostatnio potrzebowałem zmienić kilka rzeczy w tejże – nic zaawansowanego. Zamiana paru linków to tu to tam. Nic co bym podejrzewał przyczyni się do powstania tego wpisu. Linki podmieniłem i wygenerowałem wersję debug do testów lokalnych i release do sklepu. Testuję. Na debug wszystko śmiga, release wywala się w dziwnych miejscach. Hmm…
Odpalam zatem projekt w Android Studio i śledzę logi. Debug – masa logów, jak na Androida przystał, ale nic nadzwyczajnego. Build Release – wśród morza szarości czerwony komunikat.
E/SQLiteLog: (1) no such column: a
A poniżej zapytanie: SELECT COUNT(*) FROM `banners` WHERE `a` = ?
. Mamy tabelę ale nie sądzę aby ktoś tak nazwał jakąkolwiek kolumnę. Pierwsze podejrzenie, że może w jakiś sposób nazwa kolumny została przez przypadek zmieniona dla trybu release (choć wydało się to dziwne, że tylko dla release) bo wcześniejsza wersja działała. Jednak sprawdzenie klasy, z której generowana była tabela banners
nic nie dały. Kolumny jak nic nazywały się prawidłowo.
Jako, że nie dają mi spokoju takie nierozwiązane sprawy zasiadłem do dalszych poszukiwań. Na warsztat poszedł plik build.gradle
czyli plik odpowiedzialny za wszelkie ustawienia konfiguracyjne per build. Tam od razu rzuciło mi się w oczy minifyEnabled true
– hmm czyżby minifikacja działała tak superaśnie, że popsuła aplikację w trybie release? Szybkie sprawdzenie komentujące tę linię i voilà – działa. No to pytamy wujka google’a z czym to się je. Pierwszy link do dokumentacji Androida na developer.android.com a tam czytamy:
However, it’s important that you do enable code shrinking on your final APK used for testing, because it might introduce bugs if you do not sufficiently customize which code to keep.
No tak czyli super – zmniejszy kod (i go obfuskujemy), ale przy okazji popsuje się nam co nieco jeśli odpowiednio mu nie powiemy czego nie powinien tykać 🙂
Z dokumentacji dowiedziałem, się, że reguły odnośnie tego co ma być zmniejszane a co nie siedzą w plikach proguard-*. Ale jak to możliwe, że wcześniej build release działał a zbudowana apka u mnie już nie?
Otworzenie pliku proguard-rules.pro
wyjawiło tajemnicę. Na samej górze w komentarzu widnieje takie cuś:
# Add project specific ProGuard rules here. # By default, the flags in this file are appended to flags specified # in C:\Users\<UserName>\AppData\Local\Android\sdk/tools/proguard/proguard-android.txt # You can edit the include path and order by changing the proguardFiles # directive in build.gradle.
Zatem pewnie część reguł odnośnie tego co ma być shrinkowane a co nie, była w tym pliku na dysku i nie została wrzucona do repozytorium. Błąd programisty powiecie – zgoda, błąd Androida/proguarda – trochę także. Wydaje mi się, że minifikacja/obfuskacja domyślnie powinna być robiona tak, aby nie powodować, że projekt będzie się wysypywał po niej. I to jeszcze tylko w runtime! Lepszym chyba wyjście byłoby ustawić jakiś minimalny próg i ręcznie go zwiększać a nie minifikować na maksa a jak coś się psuje to martw się developerze abyś pamiętał dodać odpowiedni wpis do pliku proguard-rules.pro. Tak czy inaczej jedna dodatkowa linijka w pliku wyłączająca spod reguł większość klas projektu i aplikacja znów zaczęła działać jak przykazał.
Founder of Octal Solutions a .NET software house.
Passionate dev, blogger, occasionally speaker, one of the leaders of Wroc.NET user group. Microsoft MVP. Podcaster – Ostrapila.pl