web-dev-qa-db-fra.com

Comment utilisez-vous habituellement les entrées de journal des balises? (Android)

Je suppose que la plupart d’entre vous connaissez Android.util.Log Toutes les méthodes de journalisation acceptent le «argument de chaîne» comme premier argument.

Et ma question est Comment marquez-vous habituellement vos journaux dans vos applications? J'ai vu un hardcode comme celui-ci:

public class MyActivity extends Activity {
    private static final String TAG = "MyActivity";
    //...
    public void method () {
        //...
        Log.d(TAG, "Some logging");
    }
}

Cela ne semble pas bien à cause de nombreuses raisons:

  • Vous pouvez me dire que ce code n'a pas de code dur, mais c'est le cas.
  • Mon application peut avoir un nombre quelconque de classes dans différents packages portant le même nom. Il serait donc difficile de lire le journal.
  • Ce n'est pas flexible. Vous avez toujours mis un TAG de champ privé dans votre classe.

Existe-t-il un moyen intéressant d'obtenir un TAG pour un cours?

76
andrii

J'utilise un tag, mais je l'initialise comme ceci:

private static final String TAG = MyActivity.class.getName();

De cette façon, lorsque je refacturerai mon code, le tag changera en conséquence.

150
gianpi

Je crée généralement une classe App qui se trouve dans un package différent et contient des méthodes statiques utiles. L'une de ces méthodes est une méthode getTag(). Ainsi, je peux obtenir le TAG partout .
App class ressemble à ceci:

EDIT: Amélioration du commentaire de la foule (Merci :))

public class App {

    public static String getTag() {
        String tag = "";
        final StackTraceElement[] ste = Thread.currentThread().getStackTrace();
        for (int i = 0; i < ste.length; i++) {
            if (ste[i].getMethodName().equals("getTag")) {
                tag = "("+ste[i + 1].getFileName() + ":" + ste[i + 1].getLineNumber()+")";
            }
        }
        return tag;
    }

}

Et quand je veux l'utiliser:

Log.i(App.getTag(), "Your message here");

Le résultat de la méthode getTag est le nom de la classe de l'appelant (avec le nom du package) et le numéro de ligne d'où la getTag est appelée, pour faciliter le débogage.

12
Yaniv

J'aime améliorer la réponse de Yaniv Si vous avez le journal dans ce format (nomfichier.Java:XX), vous pouvez lier le raccourci de la même manière que lorsqu'il y a une erreur ligne en question juste en cliquant sur le logcat

Je mets cela dans mon application étendue pour que je puisse l'utiliser dans tous les autres fichiers

public static String getTag() {
    String tag = "";
    final StackTraceElement[] ste = Thread.currentThread().getStackTrace();
    for (int i = 0; i < ste.length; i++) {
        if (ste[i].getMethodName().equals("getTag")) {
            tag = "("+ste[i + 1].getFileName() + ":" + ste[i + 1].getLineNumber()+")";
        }
    }
    return tag;
}

Capture d'écran:

7
br mob

J'ai créé une classe de variables statiques, méthodes et classes nommées S.

Voici la méthode de journalisation:

public static void L(Context ctx, Object s) {
    Log.d("CCC " + ctx.getClass().getName().replace(ctx.getPackageName(), ""), s.toString());
}

Il est appelé dans n'importe quelle classe sous la forme S.L(this, whaterver_object);. La fonction getClass().getName() ajoute également le nom du paquet. C'est pourquoi je le supprime pour éviter que la balise ne soit trop longue.

Avantages:

  1. Plus court que Log.d(TAG,
  2. Pas besoin de convertir les valeurs int en leur chaîne. Enfait pas besoin de taper toString
  3. N'oubliez pas de supprimer Log.d, car il me suffit de supprimer la méthode et les emplacements de tous les journaux sont marqués en rouge.
  4. Inutile de définir TAG en haut de l'activité car il prend le nom de la classe.
  5. La balise a un préfixe CCC (une chaîne courte et facile à saisir), de sorte qu'il est facile de répertorier uniquement vos journaux sur le moniteur Android dans Android Studio. Parfois, vous exécutez des services ou d’autres classes simultanément. Si vous devez rechercher uniquement par nom d'activité, vous ne pouvez pas savoir exactement quand une réponse de service a été obtenue et qu'une action de votre activité s'est produite. Un préfixe comme CCC aide car il vous donne des journaux chronologiques avec l’activité dans laquelle il s’est produit 
3
suku

Au lieu de mettre à jour ces chaînes lorsque je déplace du code entre méthodes ou que je renomme des méthodes, j'aime bien procéder comme suit. Philosophiquement, il semble également préférable de garder "emplacement" ou "contexte" dans la balise, pas le message.

public class MyClass {

    // note this is ALWAYS private...subclasses should define their own
    private static final LOG_TAG = MyClass.class.getName();

    public void f() {
        Log.i(LOG_TAG + ".f", "Merry Christmas!");
    }

}

L’avantage ici est que vous pouvez filtrer une seule méthode même si le contenu n’est pas statique, par exemple.

Log.i(LOG_TAG + ".f", String.valueOf(new Random().nextInt()));

Le seul inconvénient est que lorsque je renomme f() en g(), je dois garder cette chaîne à l'esprit. De plus, le refactoring IDE automatique ne les détectera pas.

Pendant un certain temps, j'étais fan de l'utilisation du nom abrégé de la classe, je veux dire LOG_TAG = MyClass.class.getSimpleName(). Je les ai trouvés plus difficiles à filtrer dans les journaux parce qu'il y avait moins de choses à faire.

2
tar

Vous pouvez utiliser this.toString() pour obtenir un identifiant unique pour la classe spécifique dans laquelle vous imprimez dans le journal. 

1
kaspermoerch

C'est une très vieille question, mais même avec une réponse mise à jour pour juillet 2018, il est préférable d'utiliser Timber. Pour consigner la journalisation correcte, les erreurs et les avertissements peuvent être envoyés à des bibliothèques de crash tierces, telles que Firebase ou Crashlytics.

Dans la classe qui implémente Application , vous devez ajouter ceci:

@Override
public void onCreate() {
    super.onCreate();
    if (BuildConfig.DEBUG) {
        Timber.plant(new Timber.DebugTree());
    } else {
        Timber.plant(new CrashReportingTree());
    }
}

/** A tree which logs important information for crash reporting. */
private static class CrashReportingTree extends Timber.Tree {
    @Override protected void log(int priority, String tag, String message, Throwable t) {
        if (priority == Log.VERBOSE || priority == Log.DEBUG) {
            return;
        }

        FakeCrashLibrary.log(priority, tag, message);

        if (t != null) {
            if (priority == Log.ERROR) {
                FakeCrashLibrary.logError(t);
            } else if (priority == Log.WARN) {
                FakeCrashLibrary.logWarning(t);
            }
        }
    }
}

N'oubliez pas la dépendance au bois.

implementation 'com.jakewharton.timber:timber:4.7.1'
0
aleksandrbel

ils utilisent Timber pour l'application IOsched 2019 pour afficher les informations de débogage:

implementation 'com.jakewharton.timber:timber:4.7.1'

class ApplicationController: Application() {

override fun onCreate() {  
    super.onCreate()
    if(BuildConfig.DEBUG){
        Timber.plant(Timber.DebugTree())
    }
}   
// enables logs for every activity and service of the application
// needs to be registered in manifest like:  
 <application
    Android:label="@string/app_name"
    Android:name=".ApplicationController"
    ... >

usage

  Timber.e("Error Message") 
  // will print ->  D/MainActivity: Error Message

  Timber.d("Debug Message");
  Timber.tag("new tag").e("error message");

notez que cela rend les journaux disponibles uniquement pendant l'état DEBUG et vous facilite la tâche de les supprimer manuellement pour le lancement sur Google Play -

lors de la publication de l'application sur le Play Store, nous devons supprimer toutes les instructions de journal de l'application, afin qu'aucune des données de l'application, telles que les informations de l'utilisateur, les données d'application masquées, les jetons d'authentification ne soient disponibles pour l'utilisateur dans logcat en texte brut.

consultez cet article https://medium.com/mindorks/better-logging-in-Android-using-timber-72e40cc2293d

0
Dan Alboteanu

Pour les utilisateurs qui visitent cette question:

private val TAG:String = this.javaClass.simpleName;
0
Pamirzameen