Mam aplikację, która używa wielu wywołań Log.d()
lub Log.e()
do debugowania. Teraz chcę stworzyć mój ostateczny pakiet do wydania. Funkcja eksportu systemu Android z Eclipse wspomina o usunięciu flagi "Debuggable"
w manifeście, który zrobiłem. Czy powinienem również skomentować wszystkie połączenia Log
w celu poprawy wydajności mojej aplikacji, czy te połączenia nie będą działały w pakiecie końcowym bez debugowania?Czy powinienem skomentować mój log wywołania podczas tworzenia mojego ostatecznego pakietu?
Odpowiedz
Podklasowałem klasę Log do klasy o nazwie Trace, która odzwierciedla metody w dzienniku. Robię więc Trace.d (TAG, "bla"), a następnie w metodzie Trace.d kod wykonuje się tylko na podstawie statycznej zmiennej klasy końcowej o nazwie LOGGING_LEVEL, która ma poziomy 1-5 (brak, tylko błędy, błędy & ostrzeżenia , błędy & ostrzeżenia & info i wszystko w tym debugowanie). Podczas tworzenia produkcyjnego pliku APK program Proguard usuwa cały kod, który nie jest używany w aplikacji, więc robi to za mnie.
Dla mnie rejestrowanie jest zbyt ważne, aby usunąć je ze źródła, ale musi zostać usunięte z aplikacji produkcyjnej, ze względu na wydajność, bezpieczeństwo i własności intelektualnej.
Taka struktura pozwala mi dodać dużo więcej logowania do aplikacji, która sprawia problemy debugowania dużo łatwiej, ale z żadnego wpływu na produkcję APK
public class Trace
{
public static final int NONE = 0;
public static final int ERRORS_ONLY = 1;
public static final int ERRORS_WARNINGS = 2;
public static final int ERRORS_WARNINGS_INFO = 3;
public static final int ERRORS_WARNINGS_INFO_DEBUG = 4;
private static final int LOGGING_LEVEL = ERRORS_ONLY; // Errors + warnings + info + debug (default)
public static void e(String tag, String msg)
{
if (LOGGING_LEVEL >=1) Log.e(tag,msg);
}
public static void e(String tag, String msg, Exception e)
{
if (LOGGING_LEVEL >=1) Log.e(tag,msg,e);
}
public static void w(String tag, String msg)
{
if (LOGGING_LEVEL >=2) Log.w(tag, msg);
}
public static void i(String tag, String msg)
{
if (LOGGING_LEVEL >=3) Log.i(tag,msg);
}
public static void d(String tag, String msg)
{
if (LOGGING_LEVEL >=4) Log.d(tag, msg);
}
}
Od developer.android.com:
Wyłącz rejestrowanie i debugowanie i oczyścić dane/pliki do zwolnienia, należy upewnić się, że obiekty debugowania są wyłączone i że debugowania i inne niepotrzebne Dane/pliki są usuwane z projektu aplikacji .
Usuń atrybut android: debuggable = "true" z elementu manifestu w postaci . Usuń pliki dziennika , pliki kopii zapasowych i inne niepotrzebne pliki z projektu aplikacji . Sprawdź poufne dane prywatne lub i usuń je jako wymagane . Dezaktywuj wszystkie wywołania metod Log w kodzie źródłowym.
Nie byłbym tak surowy, aby usunąć wszystkie rejestracje, ale na pewno debugować logowanie. –
Już widziałem tę informację na stronie internetowej dla Androida, ale nie było dla mnie jasne, czy istnieje mechanizm "Wyłączania rejestrowania" inny niż komentowanie wszystkiego. Ponadto, gdy mówią "Dezaktywuj wszelkie wywołania metod Logowania w kodzie źródłowym", nie jest jasne, czy mają na myśli "komentarz", czy jest inny sposób. – jmbouffard
Zastanawiam się, co napisał hipokryta? dziennik Androida jest w 98% wypełniony wiadomościami z aplikacji i usług Android. może to, co mieli na myśli, to "wyłączyć wszystkie rejestracje, aby nie zaśmiecały dziennika, gdy chcemy znaleźć nasze logi". –
To sprawiło mi sprawdzić moje założenie, że log.d
linie kodu, który jakoś nie pojawiają się na podpisanym apk uwalnianiu bez debuggable flag set w manifeście, myliłem, nadal zjawić się.
Szybkie wyszukiwanie na SO doprowadziło mnie do zaakceptowanej odpowiedzi na to pytanie: Remove all debug logging calls before publishing: are there tools to do this?
działa bardzo dobrze i nie trzeba zmieniać żadnego kodu.
Wydaje się być dobrym rozwiązaniem, ale nie jestem pewien, czy chcę używać Proguard. – jmbouffard
@jmbouffard: Jeśli już używasz Anta do zbudowania apk wersji, to całkiem łatwo jest dodać Proguard, ponieważ jest już cel w main_rules.xml pakietu SDK. Jeśli nie znasz Anta, to zgadzam się, może to być trochę uciążliwe. – NickT
Chciałbym usunąć jak poniższy kod logowania:
-assumenosideeffects class android.util.Log {
public static boolean isLoggable(java.lang.String, int);
public static int v(...);
public static int i(...);
public static int w(...);
public static int d(...);
public static int e(...);
public static java.lang.String getStackTraceString(java.lang.Throwable);
}
-assumenosideeffects class java.lang.Exception {
public void printStackTrace();
}
-assumenosideeffects class * implements org.slf4j.Logger {
public void trace(...);
public void debug(...);
public void info(...);
public void warn(...);
public void error(...);
public boolean isTraceEnabled(...);
public boolean isDebugEnabled(...);
public boolean isInfoEnabled(...);
public boolean isWarnEnabled(...);
public boolean isErrorEnabled(...);
}
W razie potrzeby kategorie błędów i ostrzeżeń mogą zostać zachowane.Ale upewnij się, że optymalizacja i zmniejszanie jest włączone tylko dla kompilacji, a następnie usunięcie kodu jest skuteczne
- 1. Czy powinienem używać "ostatecznego" modyfikatora podczas tworzenia obiektów Date?
- 2. Problem podczas tworzenia mojego pierwszego CocoaPod
- 3. błąd podczas tworzenia archiwum mojego Cocos2d aplikacji
- 4. Uwzględnianie/wykluczanie plików podczas tworzenia pakietu Azure
- 5. Czy log (n!) = Θ (n · log (n))?
- 6. Dlaczego brakuje zestawu mojego projektu z pakietu podczas debugowania?
- 7. Czy powinienem zawsze owijać mój kod w try ... catch blocks?
- 8. Dlaczego otrzymuję AssociationTypeMismatch podczas tworzenia mojego obiektu modelu?
- 9. Jak określić zależności podczas tworzenia pliku setup.py dla pakietu python
- 10. Czy log (a * b) jest zawsze szybszy w programie Matlab niż log (a) + log (b)?
- 11. Łączenie wielu plików podczas tworzenia pakietu w R
- 12. Wyszukiwanie ostatecznego rozmiaru Textarea
- 13. Czy powinienem zmienić mój serwis narzędziowy na moduł utilities.pm?
- 14. Jak uniknąć powtarzania się podczas tworzenia rejestratora?
- 15. Błąd podpisanego pakietu aplikacji Android do wywołania
- 16. Czy powinienem martwić się kodowaniem podczas serializacji?
- 17. Co powinienem nazwać mój plik klasy PHP?
- 18. Jak powinienem zorganizować mój projekt OCaml?
- 19. Czy "__module__" jest gwarantowane podczas tworzenia klasy?
- 20. Czy nowa pamięć LINQ podczas tworzenia zwraca
- 21. Czy istnieje zdarzenie System podczas tworzenia procesów?
- 22. Django: show/log ORM sql wywołania z powłoki Pythona
- 23. Dlaczego mój log jest w przestrzeni nazw standardu?
- 24. Zmiana wiązania `Proc` podczas wywołania
- 25. dział log-log z seaborn jointgrid
- 26. Podczas tworzenia virtualenv
- 27. Przyczyna awarii podczas tworzenia użytkownika
- 28. Błąd podczas instalacji pakietu
- 29. Obsługa obrazów podczas tworzenia oprogramowania
- 30. Dlaczego powinienem dodawać zależności rozwojowe do mojego gemspec?
Myślałem, że to już zostało uwzględnione w klasie Log Androida. Dlaczego nie możemy po prostu wykonać Log.setLogLevel (Log.ERROR)? Jeśli nie, twoje rozwiązanie wydaje się naprawdę dobre. – jmbouffard
"bez żadnego wpływu na produkcję APK" ... źle. to dobrze znany anty-wzór. Problem polega na tym, że argument msg jest zawsze oceniany niezależnie od tego, czy faktycznie logujesz wiadomość. na przykład Trace.e ("blah", "error was:" + error.getCode() + ", ruh roh!"). niezależnie od tego, czy logujesz się, czy nie, utworzono trzy tymczasowe ciągi znaków i dwa niepotrzebne wywołania metod. –
@jmbouffard Na Log nie ma metody o nazwie setLogLevel() –