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:
Existe-t-il un moyen intéressant d'obtenir un TAG pour un cours?
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.
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.
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:
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:
Log.d(TAG,
toString
Log.d
, car il me suffit de supprimer la méthode et les emplacements de tous les journaux sont marqués en rouge.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 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.
Vous pouvez utiliser this.toString()
pour obtenir un identifiant unique pour la classe spécifique dans laquelle vous imprimez dans le journal.
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'
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
Pour les utilisateurs qui visitent cette question:
private val TAG:String = this.javaClass.simpleName;