Jak usunąć wszystkie połączenia logowania debugowania przed opublikowaniem aplikacji w Google Play? [zamknięte]

Według Google, muszę "dezaktywować wszelkie wywołania logowania metod w kodzie źródłowym " przed opublikowaniem mojej aplikacji na Androida. Wyciąg z sekcji 5 listy kontrolnej publikacji :

Upewnij się, że dezaktywujesz rejestrowanie i wyłącz opcję debugowania przed zbudowaniem aplikacji do wydania. Możesz dezaktywować rejestrowanie, usuwając wywołania do metod logowania w plikach źródłowych.

Mój projekt open-source jest duży i to jest ból, aby to zrobić ręcznie za każdym razem, gdy wypuszczam. Dodatkowo usunięcie linii dziennika jest potencjalnie trudne, na przykład:

if(condition)
  Log.d(LOG_TAG, "Something");
data.load();
data.show();

Jeśli skomentuję linię logu, to warunek dotyczy następnej linii, a prawdopodobieństwo, że load () nie zostanie wywołane. Czy takie sytuacje są na tyle rzadkie, że mogę zdecydować, że nie powinny istnieć?

To jest na oficjalnej liście kontrolnej, więc myślę, że wiele osób robi to regularnie.
Jak skutecznie, ale bezpiecznie usunąć wszystkie linie dziennika?

Author: Thunder, 2010-03-15

21 answers

Uważam, że o wiele łatwiejszym rozwiązaniem jest zapomnieć o wszystkich sprawdzeniach ifwszędzie i po prostu użyć ProGuard, aby usunąć wszelkie wywołania metod Log.d() lub Log.v(), gdy wywołamy nasz cel Ant {6]}.

W ten sposób, zawsze mamy informacje o debugowaniu dla zwykłych kompilacji i nie musimy wprowadzać żadnych zmian w kodzie dla kompilacji release. ProGuard może również wykonywać wiele przejść nad kodem bajtowym, aby usunąć inne niepożądane instrukcje, puste bloki i może automatycznie wbudowywać krótkie metody w stosownych przypadkach.

Na przykład, oto bardzo podstawowa konfiguracja ProGuard dla Androida:

-dontskipnonpubliclibraryclasses
-dontobfuscate
-forceprocessing
-optimizationpasses 5

-keep class * extends android.app.Activity
-assumenosideeffects class android.util.Log {
    public static *** d(...);
    public static *** v(...);
}

Więc możesz zapisać to do pliku, a następnie wywołać ProGuard z Ant, przekazując właśnie skompilowany JAR i platformę Android jar, którego używasz.

Zobacz także przykłady w podręczniku ProGuard.


Aktualizacja (4,5 roku później): obecnie używałem Timber do logowania Androida.

Nie tylko jest trochę ładniejszy niż domyślny Log implementacja-znacznik dziennika jest ustawiany automatycznie i łatwo jest logować sformatowane ciągi znaków i wyjątki - ale można również określić różne zachowania logowania w czasie wykonywania.

W tym przykładzie instrukcje logowania będą zapisywane do logcat tylko w kompilacjach debugowania mojej aplikacji:

[[10]}drewno jest ustawione w moim Application onCreate() "metoda": {]}
if (BuildConfig.DEBUG) {
  Timber.plant(new Timber.DebugTree());
}

Wtedy gdziekolwiek indziej w moim kodzie mogę się łatwo zalogować:

Timber.d("Downloading URL: %s", url);
try {
  // ...
} catch (IOException ioe) {
  Timber.e(ioe, "Bad things happened!");
}
Więcej informacji można znaleźć w aplikacji do próbkowania drewna

, gdzie wszystkie instrukcje logcat są wysyłane do logcat podczas programowania, a podczas produkcji nie są rejestrowane żadne instrukcje debugowania, ale błędy są cicho zgłaszane do Crashlytics.

 436
Author: Christopher Orr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-04 16:45:36

Wszystkie dobre odpowiedzi, ale kiedy skończyłem z moim rozwojem, nie chciałem ani używać instrukcji if wokół wszystkich wywołań dziennika, ani nie chciałem używać zewnętrznych narzędzi.

Więc rozwiązaniem, którego używam, jest zastąpienie Androida.util.Klasa Log z własną klasą Log:
public class Log {
    static final boolean LOG = false;

    public static void i(String tag, String string) {
        if (LOG) android.util.Log.i(tag, string);
    }
    public static void e(String tag, String string) {
        if (LOG) android.util.Log.e(tag, string);
    }
    public static void d(String tag, String string) {
        if (LOG) android.util.Log.d(tag, string);
    }
    public static void v(String tag, String string) {
        if (LOG) android.util.Log.v(tag, string);
    }
    public static void w(String tag, String string) {
        if (LOG) android.util.Log.w(tag, string);
    }
}

Jedyną rzeczą, którą musiałem zrobić we wszystkich plikach źródłowych, było zastąpienie importu Androida.util.Zaloguj się z moją własną klasą.

 107
Author: Reiner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-28 02:53:22

Proponuję mieć gdzieś statyczny boolean wskazujący czy logować czy nie:

class MyDebug {
  static final boolean LOG = true;
}

Więc gdziekolwiek chcesz się zalogować, po prostu zrób to:

if (MyDebug.LOG) {
  if (condition) Log.i(...);
}

Teraz, gdy ustawisz MyDebug.LOG to false, kompilator usunie cały kod wewnątrz takich sprawdzeń (ponieważ jest to końcowy wynik statyczny, wie w czasie kompilacji, że kod nie jest używany.)

W przypadku większych projektów, możesz zacząć mieć booleany w poszczególnych plikach, aby móc łatwo włączyć lub wyłączyć Logowanie jako potrzebne. Na przykład są to różne stałe logowania, które mamy w Menedżerze okien:

static final String TAG = "WindowManager";
static final boolean DEBUG = false;
static final boolean DEBUG_FOCUS = false;
static final boolean DEBUG_ANIM = false;
static final boolean DEBUG_LAYOUT = false;
static final boolean DEBUG_RESIZE = false;
static final boolean DEBUG_LAYERS = false;
static final boolean DEBUG_INPUT = false;
static final boolean DEBUG_INPUT_METHOD = false;
static final boolean DEBUG_VISIBILITY = false;
static final boolean DEBUG_WINDOW_MOVEMENT = false;
static final boolean DEBUG_ORIENTATION = false;
static final boolean DEBUG_APP_TRANSITIONS = false;
static final boolean DEBUG_STARTING_WINDOW = false;
static final boolean DEBUG_REORDER = false;
static final boolean DEBUG_WALLPAPER = false;
static final boolean SHOW_TRANSACTIONS = false;
static final boolean HIDE_STACK_CRAWLS = true;
static final boolean MEASURE_LATENCY = false;

Z odpowiednim kodem jak:

    if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT) Log.v(
        TAG, "Adding window " + window + " at "
        + (i+1) + " of " + mWindows.size() + " (after " + pos + ")");
 57
Author: hackbod,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-15 15:35:24

Rozwiązanie Proguard Christophera jest najlepsze, ale jeśli z jakiegoś powodu nie lubisz Proguard, oto bardzo nowoczesne rozwiązanie: {]}

Komentarze:

find . -name "*\.java" | xargs grep -l 'Log\.' | xargs sed -i 's/Log\./;\/\/ Log\./g'

Dzienniki Uncomment:

find . -name "*\.java" | xargs grep -l 'Log\.' | xargs sed -i 's/;\/\/ Log\./Log\./g'

Ograniczenie polega na tym, że instrukcje logowania nie mogą rozciągać się na wiele linii.

(wykonaj te linie w powłoce uniksowej w katalogu głównym projektu. Jeśli używasz systemu Windows, uzyskaj warstwę Uniksa lub użyj równoważnych komend systemu Windows)

 29
Author: Nicolas Raoul,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-07 05:47:44

Chciałbym dodać kilka szczegółów dotyczących używania Proguard z Androidem Studio i gradle, ponieważ miałem wiele problemów z usunięciem linii logów z ostatecznego pliku binarnego.

Aby wykonać assumenosideeffects w Proguard działa, jest warunkiem wstępnym.

W Twoim pliku gradle, musisz określić użycie proguard-android-optimize.txt jako domyślnego pliku.

buildTypes {
    release {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'

        // With the file below, it does not work!
        //proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}

Właściwie, w domyślnym pliku proguard-android.txt optymalizacja jest wyłączona z dwoma flagami:

-dontoptimize
-dontpreverify

Plik proguard-android-optimize.txt nie dodaje tych linie, więc teraz {[3] } może działać.

Potem, 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ść dzienników, może użyć Logback dla Androida i aktywować dzienniki, aby dzienniki mogły zostać przekierowane do pliku lub do LogCat.

Jeśli naprawdę muszę usunąć logi z ostatecznej biblioteki, dodaję do mojego pliku Proguard (po włączeniu proguard-android-optimize.txt Plik oczywiście):

-assumenosideeffects class * implements org.slf4j.Logger {
    public *** trace(...);
    public *** debug(...);
    public *** info(...);
    public *** warn(...);
    public *** error(...);
}
 15
Author: Vincent Hiribarren,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-24 17:48:34

Użyłem klasy LogUtils jak w przykładowej aplikacji Google IO. Zmodyfikowałem to tak, aby używać stałej debugowania specyficznej dla aplikacji zamiast BuildConfig.DEBUG ponieważ BuildConfig.DEBUG jest zawodny . Następnie na moich zajęciach mam następujące.

import static my.app.util.LogUtils.makeLogTag;
import static my.app.util.LogUtils.LOGV;

public class MyActivity extends FragmentActivity {
  private static final String TAG = makeLogTag(MyActivity.class);

  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    LOGV(TAG, "my message");
  }
}
 8
Author: JosephL,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-03 20:48:31

Rozważyłbym użycie urządzenia rejestrującego roboguice zamiast wbudowanego Androida.util.Log

Ich funkcja automatycznie wyłącza dzienniki debugowania i verbose dla wersji kompilacji. Dodatkowo, dostajesz kilka ciekawych funkcji za darmo (np. konfigurowalne zachowanie logowania, dodatkowe dane dla każdego dziennika i wiele innych)

Używanie proguarda może być dość kłopotliwe i nie zadałbym sobie trudu konfiguracji i uczynienia go działającym z Twoją aplikacją, chyba że masz dobry powód tego (wyłączenie logów nie jest dobre)

 7
Author: Zvi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-27 23:46:32

Sugeruję użycie drewna Jake ' a Whartona.]}

Https://github.com/JakeWharton/timber

Rozwiązuje problem z włączaniem/wyłączaniem oraz dodaje klasę tagów automagicznie

Po Prostu

public class MyApp extends Application {

  public void onCreate() {
    super.onCreate();
    //Timber
    if (BuildConfig.DEBUG) {
      Timber.plant(new DebugTree());
    }
    ...

Logi będą używane tylko w Twoim debug ver, a następnie użyj

Timber.d("lol");

Lub

Timber.i("lol says %s","lol");

Do wydruku

"twoja klasa / msg" bez określenia tagu

 7
Author: AndroidGecko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-20 09:13:12

Na Androida.util.Log umożliwia włączenie / wyłączenie logu:

public static native boolean isLoggable(String tag, int level);

Domyślnie metoda isLoggable(...) zwraca false, dopiero po ustawieniu urządzenia w ten sposób:

adb shell setprop log.tag.MyAppTag DEBUG

Oznacza to, że każdy dziennik powyżej poziomu debugowania może zostać wydrukowany. Odniesienie do android doc:

Sprawdza, czy Dziennik dla określonego tagu jest możliwy do zalogowania na określonym poziomie. Ustawiany jest domyślny poziom dowolnego znacznika do informacji. Oznacza to, że każdy poziom powyżej i w tym informacje będą zalogowany. Przed nawiązaniem połączenia z metodą Logowania należy sprawdzić aby sprawdzić, czy Twój tag powinien być zalogowany. Możesz zmienić domyślny poziom poprzez ustawienie właściwości systemowej: 'setprop log.tag. ' Gdzie poziom jest albo VERBOSE, DEBUG, INFO, WARN, ERROR, ASSERT, or / Align = "left" / Wyłącz wszystkie Logowanie dla Twojego tagu. Możesz również utworzyć lokalne.plik prop, który zawiera w sobie następujące: "log.tag.= "i umieść to w /data / local.rekwizyt.

Więc możemy użyć niestandardowego dziennika util: {]}

public final class Dlog 
{
    public static void v(String tag, String msg)
    {
        if (Log.isLoggable(tag, Log.VERBOSE))
            Log.v(tag, msg);
    }

    public static void d(String tag, String msg)
    {
        if (Log.isLoggable(tag, Log.DEBUG))
            Log.d(tag, msg);
    }

    public static void i(String tag, String msg)
    {
        if (Log.isLoggable(tag, Log.INFO))
            Log.i(tag, msg);
    }

    public static void w(String tag, String msg)
    {
        if (Log.isLoggable(tag, Log.WARN))
            Log.w(tag, msg);
    }

    public static void e(String tag, String msg)
    {
        if (Log.isLoggable(tag, Log.ERROR))
            Log.e(tag, msg);
    }
}
 6
Author: Richard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-06 13:21:50

Zamieszczam To rozwiązanie, które ma zastosowanie specjalnie dla użytkowników Android Studio. Niedawno odkryłem również drewno i zaimportowałem je z powodzeniem do mojej aplikacji, wykonując następujące czynności:]}

Umieść najnowszą wersję biblioteki w swoim build."gradle": {]}

compile 'com.jakewharton.timber:timber:4.1.1'

Następnie w Android Studios przejdź do edycji - > Znajdź - > Zamień w ścieżce...

Wpisz {[2] } lub jakkolwiek zdefiniowałeś swoje wiadomości logowania w polu tekstowym "Text to find". Następnie wystarczy wymienić go na Timber.e(

Tutaj wpisz opis obrazka

Kliknij Znajdź, a następnie zamień wszystkie.

Android Studios przejrzy teraz wszystkie Twoje pliki w Twoim projekcie i zastąpi wszystkie dzienniki Timberami.

Jedyny problem, jaki miałem z tą metodą jest to, że gradle wymyśla milion komunikatów o błędach, ponieważ nie może znaleźć "Timber" w importach dla każdego z Twoich plików java. Wystarczy kliknąć na błędy, a Android Studios automatycznie zaimportuje "Timber" do Twojej Javy. Once you jeśli zrobiłeś to dla wszystkich plików błędów, gradle skompiluje się ponownie.

Musisz również umieścić ten fragment kodu w swojej metodzie onCreate twojej klasy Application:

    if (BuildConfig.DEBUG) {
        Timber.plant(new Timber.DebugTree());
    }

Spowoduje to logowanie aplikacji tylko wtedy, gdy jesteś w trybie deweloperskim, a nie produkcyjnym. Możesz również mieć BuildConfig.RELEASE do logowania w trybie release.

 5
Author: Simon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-22 07:23:28

Jeśli możesz uruchomić globalny zastąp (raz), a następnie zachować pewną konwencję kodowania, możesz postępować zgodnie ze wzorem często używanym w systemie Android framework.

Zamiast pisać

Log.d(TAG, string1 + string2 + arg3.toString());

Niech to będzie

if (BuildConfig.DEBUG) Log.d(TAG, string1 + String.format("%.2f", arg2) + arg3.toString());

Teraz proguard może usunąć StringBuilder oraz wszystkie ciągi i metody, których używa po drodze, ze zoptymalizowanego Dex-a wydania. Użyj proguard-android-optimize.txt i nie musisz się martwić o Androida.util.Log w Twoim proguard-rules.pro:

android {
  …
  buildTypes {
    release {
      minifyEnabled true
      proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
  }
}

Z Android Studio gradle wtyczka, BuildConfig.DEBUG jest dość niezawodna, więc nie potrzebujesz dodatkowych stałych, aby kontrolować usuwanie.

 4
Author: Alex Cohn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-29 12:19:48

Tutaj wpisz opis obrazka

To właśnie robiłem w moich projektach z Androidem..

W Android Studio możemy wykonać podobną operację, Ctrl + Shift + F, aby znaleźć z całego projektu (Command+Shift+F w MacOs) i Ctrl + Shift + R, aby zastąpić ((Command+Shift+R W MacOs))

 3
Author: Lins Louis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-12 11:19:14

Mam bardzo proste rozwiązanie. Używam IntelliJ do rozwoju, więc szczegóły są różne, ale pomysł powinien mieć zastosowanie we wszystkich IDE.

Wybieram do korzenia mojego drzewa źródłowego, klikam prawym przyciskiem myszy i wybieram "zamień". Następnie wybieram zastąpienie wszystkich " Log."z" / / Log.". Spowoduje to usunięcie wszystkich instrukcji dziennika. Aby umieścić je z powrotem później powtarzam to samo replace ale tym razem jako replace all " / / Log."z" logiem.".

Działa po prostu świetnie dla mnie. Pamiętaj tylko, aby ustawić zastąp jako wrażliwy na wielkość liter, aby uniknąć wypadki takie jak " Dialog.". Aby uzyskać dodatkową pewność, możesz również wykonać pierwszy krok za pomocą " Log."jako ciąg do wyszukiwania.

Genialne.

 2
Author: kg_sYy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-20 18:38:45

Jako komentarz zserge zasugerował,

[3]}drewno jest bardzo ładne, ale jeśli masz już istniejący projekt - możesz spróbować github.com/zserge/log . Jest to zamiennik drop-in dla Androida.util.Drewna i posiada większość cech drewna, a nawet więcej.

Jego Biblioteka dziennika zapewnia prosty przełącznik włączania / wyłączania drukowania dziennika, jak poniżej.

Dodatkowo, to tylko wymaga zmiany import linii, a nic nie musi zmiana dla Log.d(...); instrukcji.

if (!BuildConfig.DEBUG)
    Log.usePrinter(Log.ANDROID, false); // from now on Log.d etc do nothing and is likely to be optimized with JIT
 2
Author: Youngjae,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:50

Poprawiłem powyższe rozwiązanie, zapewniając wsparcie dla różnych poziomów dziennika i zmieniając poziomy dziennika automatycznie w zależności od tego, czy kod jest uruchamiany na urządzeniu na żywo lub na emulatorze.

public class Log {

final static int WARN = 1;
final static int INFO = 2;
final static int DEBUG = 3;
final static int VERB = 4;

static int LOG_LEVEL;

static
{
    if ("google_sdk".equals(Build.PRODUCT) || "sdk".equals(Build.PRODUCT)) {
        LOG_LEVEL = VERB;
    } else {
        LOG_LEVEL = INFO;
    }

}


/**
 *Error
 */
public static void e(String tag, String string)
{
        android.util.Log.e(tag, string);
}

/**
 * Warn
 */
public static void w(String tag, String string)
{
        android.util.Log.w(tag, string);
}

/**
 * Info
 */
public static void i(String tag, String string)
{
    if(LOG_LEVEL >= INFO)
    {
        android.util.Log.i(tag, string);
    }
}

/**
 * Debug
 */
public static void d(String tag, String string)
{
    if(LOG_LEVEL >= DEBUG)
    {
        android.util.Log.d(tag, string);
    }
}

/**
 * Verbose
 */
public static void v(String tag, String string)
{
    if(LOG_LEVEL >= VERB)
    {
        android.util.Log.v(tag, string);
    }
}


}
 1
Author: danwms,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-29 10:12:22

ProGuard zrobi to za Ciebie na release build, a teraz dobra wiadomość z android.com:

Http://developer.android.com/tools/help/proguard.html

Narzędzie ProGuard kurczy, optymalizuje i zaciemnia kod, usuwając nieużywany kod i zmieniając nazwy klas, pól i metod o niejasnych semantycznie nazwach. Rezultatem jest mniejszy rozmiar .plik apk, który jest trudniejszy do inżynierii wstecznej. Ponieważ ProGuard utrudnia inżynierię wsteczną aplikacji, ważne jest, aby używać go, gdy aplikacja korzysta z funkcji wrażliwych na bezpieczeństwo, takich jak Licencjonowanie aplikacji.

ProGuard jest zintegrowany z systemem Android, więc nie musisz go wywoływać ręcznie. ProGuard działa tylko wtedy, gdy budujesz aplikację w trybie release, więc nie musisz zajmować się zaciemnionym kodem, gdy budujesz aplikację w trybie debugowania. Posiadanie ProGuard run jest całkowicie opcjonalne, ale bardzo polecam.

Ten dokument opisuje, jak włączyć i skonfigurować program ProGuard, a także użyć narzędzia retrace do dekodowania zaciemnionych śladów stosu

 1
Author: Max Gold,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-26 07:39:52

Dodaj następujące do proguard-rules.txt Plik

-assumenosideeffects class android.util.Log {
  public static *** d(...);
  public static *** w(...);
  public static *** v(...);
  public static *** i(...);
}
 1
Author: eranga,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-02 13:37:37

Lubię używać loga.d (TAG, jakiś ciąg, często ciąg.format ()).

TAG jest zawsze nazwą klasy

Transform Log.d (TAG, -- > Logd (w tekście twojej klasy

private void Logd(String str){
    if (MainClass.debug) Log.d(className, str);
}

W ten sposób, gdy będziesz gotowy do wydania wersji, Ustaw MainClass.debug do false!

 0
Author: user462990,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-14 13:53:59

Dzienniki mogą być usuwane za pomocą bash w Linuksie i sed:

find . -name "*\.java" | xargs sed -ri ':a; s%Log\.[ivdwe].*\);%;%; ta; /Log\.[ivdwe]/ !b; N; ba'

Działa dla dzienników wieloliniowych. W tym rozwiązaniu można mieć pewność, że logi nie występują w kodzie produkcyjnym.

 0
Author: sylwano,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-12 10:42:07

Wiem, że to stare pytanie, ale dlaczego nie zamieniłeś wszystkich logów na coś takiego Boolean logCallWasHere = true; / / - - - reszta twojego logu tutaj

Dlatego będziesz wiedział, kiedy chcesz je odłożyć, a nie będą miały wpływu na wywołanie polecenia IF:)

 0
Author: masood elsad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-06 23:40:59

Najprostszy sposób;

Użyj DebugLog

Wszystkie dzienniki są wyłączone przez DebugLog po wydaniu aplikacji.

Https://github.com/MustafaFerhan/DebugLog

 -1
Author: Mustafa Ferhan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-01 08:55:35