Według Google muszę „ dezaktywować wszelkie wywołania metod rejestrowania w kodzie źródłowym ” przed opublikowaniem mojej aplikacji na Androida w Google Play. Wyciąg z sekcji 3 listy kontrolnej publikacji :
Przed skompilowaniem aplikacji do wydania należy wyłączyć rejestrowanie i opcję debugowania. Można dezaktywować rejestrowanie, usuwając wywołania metod rejestrowania w plikach źródłowych.
Mój projekt typu open source jest duży i trudno go robić ręcznie za każdym razem, gdy go wypuszczam. Ponadto usunięcie wiersza dziennika jest potencjalnie trudne, na przykład:
if(condition)
Log.d(LOG_TAG, "Something");
data.load();
data.show();
Jeśli komentuję wiersz dziennika, wówczas warunek dotyczy następnego wiersza, a szanse, że load () nie zostaną wywołane. Czy takie sytuacje są na tyle rzadkie, że mogę zdecydować, że nie powinny istnieć?
Czy istnieje lepszy sposób na zrobienie tego na poziomie kodu źródłowego? A może sprytna składnia ProGuard, aby skutecznie, ale bezpiecznie usuwać wszystkie wiersze dziennika?
źródło
sed 's_^\(\s*Log\.\)_;//'`date|tr -s \ -`'\1_g'
zamiast tego.Odpowiedzi:
Uważam, że o wiele łatwiejszym rozwiązaniem jest zapomnienie wszystkich
if
kontroli w dowolnym miejscu i po prostu skorzystanie z ProGuard, aby usunąć wszelkie wywołania metodLog.d()
lubLog.v()
metody, gdy wywołujemy naszrelease
cel Ant .W ten sposób zawsze otrzymujemy informacje debugowania dla regularnych kompilacji i nie musimy wprowadzać żadnych zmian w kodzie dla kompilacji wersji. ProGuard może również wykonywać wiele przejść przez kod bajtowy w celu usunięcia innych niepożądanych instrukcji, pustych bloków i może automatycznie wstawiać krótkie metody, jeśli to konieczne.
Na przykład, oto bardzo podstawowa konfiguracja ProGuard dla Androida:
Więc zapisz to w pliku, a następnie zadzwoń do ProGuard z Anta, przekazując właśnie skompilowany plik JAR i używany plik JAR platformy Android.
Zobacz także przykłady w podręczniku ProGuard.
Aktualizacja (4,5 roku później): Obecnie korzystam z rejestrowania drewna w systemie Android.
Jest nie tylko nieco ładniejszy niż domyślna
Log
implementacja - znacznik dziennika jest ustawiany automatycznie, a także łatwo rejestrować sformatowane ciągi i wyjątki - ale można także określić różne zachowania rejestrowania w czasie wykonywania.W tym przykładzie instrukcje rejestrowania zostaną zapisane do logcat tylko w kompilacjach debugowania mojej aplikacji:
W mojej
Application
onCreate()
metodzie skonfigurowano drewno :Następnie gdziekolwiek indziej w moim kodzie mogę się łatwo zalogować:
Zobacz przykładową aplikację Timber, aby uzyskać bardziej zaawansowany przykład, w którym wszystkie instrukcje dziennika są wysyłane do logcat podczas programowania, a podczas produkcji nie są rejestrowane żadne instrukcje debugowania, ale błędy są bezgłośnie zgłaszane Crashlytics.
źródło
Wszystkie dobre odpowiedzi, ale kiedy skończyłem mój rozwój, nie chciałem używać instrukcji if w obrębie wszystkich wywołań dziennika, ani nie chciałem używać narzędzi zewnętrznych.
Rozwiązaniem, którego używam, jest zastąpienie klasy android.util.Log własną klasą Log:
Jedyną rzeczą, którą musiałem zrobić we wszystkich plikach źródłowych, było zastąpienie importu android.util.Log własną klasą.
źródło
Log.d("tag", someValue.toString());
, bardzo łatwo jest zapomnieć o sprawdzeniu someValue pod kątem braku wartości zerowej, co oznacza, że może to spowodować wzrostNullPointerException
produkcji. To sugeruje bezpieczne rozwiązanie, ale oszuka cię. My,private static boolean DEBUG
a potemif(DEBUG)Log.d(TAG, msg);
String
. Kompletne rozwiązanie jest tutaj opisane . Ma to oczywiście inną wadę: każde połączenie powinno być edytowane (nie tylko jedna linia importu).static final boolean LOG = BuildConfig.DEBUG
tego pliku i nie musisz go modyfikować.Proponuję mieć gdzieś statyczną wartość logiczną wskazującą, czy należy się zalogować:
Następnie, gdziekolwiek chcesz się zalogować, po prostu zrób to:
Teraz, gdy ustawisz MyDebug.LOG na false, kompilator usunie cały kod z takich kontroli (ponieważ jest to statyczny finał, wie, że w czasie kompilacji kod nie jest używany).
W przypadku większych projektów możesz chcieć zacząć mieć logiczne wartości w poszczególnych plikach, aby móc łatwo włączyć lub wyłączyć rejestrowanie w razie potrzeby. Na przykład są to różne stałe rejestrowania, które mamy w menedżerze okien:
Z odpowiednim kodem, takim jak:
źródło
Rozwiązanie Christopher's Proguard jest najlepsze, ale jeśli z jakiegokolwiek powodu nie podoba ci się Proguard, oto bardzo mało zaawansowane rozwiązanie:
Dzienniki komentarzy:
Dzienniki odkomentowania:
Ograniczeniem jest to, że instrukcje rejestrowania nie mogą obejmować wielu linii.
(Wykonaj te wiersze w powłoce UNIX w katalogu głównym projektu. Jeśli używasz systemu Windows, uzyskaj warstwę UNIX lub użyj równoważnych poleceń systemu Windows)
źródło
//
vs.;//
)Chciałbym dodać pewne szczegóły dotyczące używania Proguard z Android Studio i gradle, ponieważ miałem wiele problemów z usunięciem linii logów z ostatecznego pliku binarnego.
Warunkiem wykonania
assumenosideeffects
prac Proguard jest spełnienie warunku wstępnego.W pliku ocen musisz określić użycie
proguard-android-optimize.txt
pliku domyślnego.W rzeczywistości w
proguard-android.txt
pliku domyślnym optymalizacja jest wyłączona z dwiema flagami:proguard-android-optimize.txt
Plik nie dodawać tych linii, więc terazassumenosideeffects
może pracować.Następnie osobiście używam SLF4J , tym bardziej, gdy rozwijam niektóre biblioteki, które są dystrybuowane do innych. Zaletą jest to, że domyślnie nie ma wyjścia. A jeśli integrator chce wyjść z dziennika, może użyć Logback dla Androida i aktywować logi, aby dzienniki mogły zostać przekierowane do pliku lub LogCat.
Jeśli naprawdę muszę usunąć dzienniki z ostatecznej biblioteki, dodaję do mojego pliku Proguard (
proguard-android-optimize.txt
oczywiście po włączeniu pliku):źródło
proguard-android-optimize.txt
domyślny plik Proguard, jak i-assumenosideeffects
niestandardowy plik Proguard! Używam shinkera R8 (obecnie domyślnego) i domyślnego logowania do Androida.Gorąco polecam użycie drewna z Jake Wharton
https://github.com/JakeWharton/timber
rozwiązuje problem z włączaniem / wyłączaniem oraz automatycznie dodaje klasę znaczników
właśnie
dzienniki będą używane tylko w wersji debugowania, a następnie użyj
lub
drukować
„Twoja klasa / msg” bez określania tagu
źródło
Użyłem klasy LogUtils jak w przykładowej aplikacji Google IO. Zmodyfikowałem to, aby użyć stałej DEBUG specyficznej dla aplikacji zamiast BuildConfig.DEBUG, ponieważ BuildConfig.DEBUG jest zawodny . Następnie w moich klasach mam następujące.
źródło
Build.DEBUG
, którego użyłem. Zrezygnowałem także z różnych „poprawnych” obejść i zastosowałem rozwiązanie podobne do twojego stylu.Rozważałbym skorzystanie z funkcji logowania roboguice zamiast wbudowanego android.util.Log
Ich funkcja automatycznie wyłącza dzienniki debugowania i pełne dla kompilacji wersji. Ponadto masz kilka fajnych funkcji za darmo (np. Konfigurowalne zachowanie rejestrowania, dodatkowe dane dla każdego dziennika i więcej)
Korzystanie z programu proguard może być dość kłopotliwe, a ja nie przejdę przez kłopot z konfiguracją i sprawieniem, aby działał z aplikacją, chyba że masz ku temu dobry powód (wyłączenie logów nie jest dobre)
źródło
Publikuję to rozwiązanie, które dotyczy w szczególności użytkowników Androida Studio. Niedawno odkryłem Timber i pomyślnie go zaimportowałem do mojej aplikacji, wykonując następujące czynności:
Umieść najnowszą wersję biblioteki w swoim build.gradle:
Następnie w Android Studios, przejdź do Edycja -> Znajdź -> Zamień na ścieżce ...
Wpisz
Log.e(TAG,
lub jakkolwiek zdefiniowałeś swoje wiadomości w polu"Text to find"
tekstowym. Następnie wystarczy go zastąpićTimber.e(
Kliknij Znajdź, a następnie zamień wszystko.
Android Studios przejrzy teraz wszystkie twoje pliki w projekcie i zastąpi wszystkie dzienniki drewna.
Jedynym problemem, jaki miałem z tą metodą, jest to, że gradle ma później milion komunikatów o błędach, ponieważ nie może znaleźć „Timber” w importach dla każdego z plików Java. Wystarczy kliknąć błędy, a Android Studios automatycznie zaimportuje „Timber” do Twojej java. Gdy zrobisz to dla wszystkich plików błędów, gradle ponownie się skompiluje.
Musisz także umieścić ten fragment kodu w
onCreate
metodzie swojejApplication
klasy:Spowoduje to rejestrowanie aplikacji tylko wtedy, gdy jesteś w trybie programowania, a nie w produkcji. Możesz również mieć
BuildConfig.RELEASE
do logowania w trybie zwolnienia.źródło
import android\.util\.Log\;
Zamień na:import android\.util\.Log\;\nimport timber\.log\.Timber\;
Na android.util.Log zapewnia sposób na włączenie / wyłączenie dziennika:
Domyślnie metoda isLoggable (...) zwraca false, tylko jeśli ustawisz w urządzeniu, jak to lubi:
Oznacza to, że można wydrukować dowolny dziennik powyżej poziomu DEBUG. Dokumentacja Androida:
Możemy więc użyć niestandardowego logu:
źródło
Jeśli można uruchomić globalny zastąpić (raz), a potem zachować pewne standardy kodowania, można śledzić wzór często używane w Android ram .
Zamiast pisać
mieć to jako
Teraz proguard może usunąć StringBuilder oraz wszystkie ciągi i metody, których używa po drodze, ze zoptymalizowanego wydania DEX. Użyj
proguard-android-optimize.txt
i nie musisz się martwić o android.util.Log wproguard-rules.pro
:Dzięki wtyczce stopniowej Android Studio jest dość niezawodny, więc nie potrzebujesz dodatkowych stałych do kontrolowania usuwania.
BuildConfig.DEBUG
źródło
To właśnie robiłem w moich projektach na Androida.
W Android Studio możemy wykonać podobną operację, naciskając Ctrl + Shift + F, aby znaleźć z całego projektu (Command + Shift + F w MacOs) i Ctrl + Shift + R, aby zamienić ((Command + Shift + R w MacOs))
źródło
Mam bardzo proste rozwiązanie. Używam IntelliJ do programowania, więc szczegóły są różne, ale pomysł powinien dotyczyć wszystkich IDE.
Wybieram katalog główny mojego drzewa źródłowego, klikam prawym przyciskiem myszy i wybieram „zamień”. Następnie wybieram zastąpienie wszystkich „Logów”. z „// Log.”. Spowoduje to usunięcie wszystkich instrukcji dziennika. Aby odłożyć je później, powtarzam tę samą zamianę, ale tym razem zastępuję wszystkie „// Log”. za pomocą „Log”.
Działa po prostu świetnie dla mnie. Pamiętaj tylko, aby ustawić zamień na wielkość liter, aby uniknąć wypadków, takich jak „Dialog”. Dla dodatkowej pewności możesz również zrobić pierwszy krok z „Log”. jako ciąg do wyszukania.
Znakomity.
źródło
Zgodnie z sugestią zserge ,
jego biblioteka dzienników zapewnia proste włączanie / wyłączanie drukowania dziennika jak poniżej.
Ponadto wymaga jedynie zmiany
import
wierszy i nic nie wymaga zmiany dlaLog.d(...);
instrukcji.źródło
Dodaj następujące do pliku proguard-rules.txt
źródło
Udoskonaliłem powyższe rozwiązanie, zapewniając obsługę różnych poziomów dziennika i automatycznie zmieniając poziomy dziennika w zależności od tego, czy kod jest uruchamiany na urządzeniu na żywo, czy na emulatorze.
źródło
ProGuard zrobi to za Ciebie w kompilacji wydania, a teraz dobra wiadomość od android.com:
http://developer.android.com/tools/help/proguard.html
Narzędzie ProGuard zmniejsza, optymalizuje i zaciemnia kod, usuwając nieużywany kod i zmieniając nazwy klas, pól i metod za pomocą semantycznie niejasnych nazw. Wynikiem jest mniejszy plik .apk, który jest trudniejszy do odtworzenia. Ponieważ ProGuard utrudnia przekształcenie aplikacji w aplikację, ważne jest, aby używać jej, gdy aplikacja korzysta z funkcji wrażliwych na bezpieczeństwo, na przykład podczas licencjonowania aplikacji.
ProGuard jest zintegrowany z systemem kompilacji systemu Android, więc nie trzeba go wywoływać ręcznie. ProGuard działa tylko podczas budowania aplikacji w trybie wydania, więc nie musisz zajmować się zaciemnionym kodem podczas budowania aplikacji w trybie debugowania. Uruchomienie ProGuard jest całkowicie opcjonalne, ale wysoce zalecane.
W tym dokumencie opisano, jak włączyć i skonfigurować ProGuard, a także użyć narzędzia do śledzenia do dekodowania zaciemnionych śladów stosu
źródło
Lubię używać Log.d (TAG, jakiś ciąg znaków, często String.format ()).
TAG jest zawsze nazwą klasy
Przekształć Log.d (TAG, -> Logd (w tekście twojej klasy
W ten sposób, gdy będziesz gotowy do wydania wersji, ustaw MainClass.debug na false!
źródło
Dzienniki można usunąć za pomocą bash w systemie Linux i sed:
Działa dla dzienników wielowierszowych. W tym rozwiązaniu możesz mieć pewność, że dzienniki nie są obecne w kodzie produkcyjnym.
źródło
Wiem, że to stare pytanie, ale dlaczego nie zastąpiłeś wszystkich wywołań dziennika czymś w rodzaju logicznego logCallWasHere = true; // --- resztę twojego dziennika tutaj
Dlatego będziesz wiedział, kiedy chcesz je odłożyć, a nie wpłyną one na twoją instrukcję if :)
źródło
Dlaczego nie po prostu zrobić
? Żadne dodatkowe biblioteki nie są potrzebne, żadne reguły proguard, które mają tendencję do psucia projektu, a kompilator Java po prostu pominie kod bajtowy dla tego wywołania podczas tworzenia kompilacji wydania.
źródło
Log.d("tag","msg");
, a także łatwo zapomnieć o napisaniuif(BuildConfig.DEBUG)
części.Oto moje rozwiązanie, jeśli nie chcesz zadzierać z dodatkowymi bibliotekami lub edytować kodu ręcznie. Stworzyłem ten notatnik Jupyter, aby przeglądał wszystkie pliki Java i komentował wszystkie komunikaty dziennika. Nie idealnie, ale wykonało to za mnie zadanie.
źródło
Moja droga:
1) włącz tryb wyboru kolumny (alt + shift + wstaw)
2) wybierz jeden Log.d (TAG, „tekst”); część „Dziennik”.
3) następnie Shift + Ctrl + Alt + J
4) kliknij strzałkę w lewo
5) wykonaj Shift + End
6) naciśnij klawisz Delete.
to usuwa wszystkie wywołania LOG na raz w pliku Java.
źródło
Możesz spróbować użyć tej prostej konwencjonalnej metody:
Ctrl+ Shift+R
zastąpić
Z
źródło
Łatwo z kotlinem, wystarczy zadeklarować kilka funkcji najwyższego poziomu
źródło
najprostszy sposób;
posługiwać się
DebugLog
Wszystkie dzienniki są wyłączane przez DebugLog po wydaniu aplikacji.
https://github.com/MustafaFerhan/DebugLog
źródło