Comment afficher de longs messages dans logcat

99

J'essaye d'afficher un long message sur logcat. Si la longueur du message est supérieure à 1000 caractères, il est cassé.

Quel est le mécanisme pour afficher tous les caractères d'un long message dans logcat?

Vasu
la source
6
Je reçois une réponse du serveur sous la forme d'une longue chaîne.
Vasu
1
Même alors, pourquoi voudriez-vous imprimer la chaîne entière, l'écrire dans un fichier ou une base de données et l'afficher - si c'est pour le débogage
Rahul Choudhary
copiez votre chaîne logcat et collez-la dans notpad, vous pouvez voir la longueur totale de la chaîne 1000.
ilango j
stackoverflow.com/questions/8888654/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Réponses:

149

Si logcat limite la longueur à 1000, vous pouvez diviser la chaîne que vous souhaitez enregistrer avec String.subString () et la consigner par morceaux. Par exemple:

int maxLogSize = 1000;
for(int i = 0; i <= veryLongString.length() / maxLogSize; i++) {
    int start = i * maxLogSize;
    int end = (i+1) * maxLogSize;
    end = end > veryLongString.length() ? veryLongString.length() : end;
    Log.v(TAG, veryLongString.substring(start, end));
}
spatulamanie
la source
Journal de chat n'imprimant que la moitié de la réponse .. comment pourrais-je obtenir la longueur de la réponse entière. vous avez dit que veryLongString.length () mais ici, il n'a imprimé que la moitié de la réponse lorsque j'imprime le résultat json dans log cat
Vasu
Mais dans la console iPhone, je reçois toute la chaîne de réponse
Vasu
vous pouvez vérifier la longueur de la réponse en écrivant length () dans le journal. Si cette valeur n'est pas celle que vous attendiez, le problème ne vient peut-être pas de la journalisation.
spatulamania
3
Je ne peux pas croire qu'Android rend les choses si difficiles!
Alston
1
Je pense que ce code enregistrera une entrée de journal supplémentaire et vide à la fin, si veryLongString.length()est un multiple de maxLogSize. Peut-être changer le <=en <.
LarsH
29

Comme suite à la réponse spatulamania, j'ai écrit une classe wrapper qui gère cela pour vous. Il vous suffit de modifier l'importation et tout consignera

public class Log {

    public static void d(String TAG, String message) {
        int maxLogSize = 2000;
        for(int i = 0; i <= message.length() / maxLogSize; i++) {
            int start = i * maxLogSize;
            int end = (i+1) * maxLogSize;
            end = end > message.length() ? message.length() : end;
            android.util.Log.d(TAG, message.substring(start, end));
        }
    }

}
Jiduvah
la source
23

Cela s'appuie sur la réponse de spatulamania, est un peu plus succinct et n'ajoutera pas de message de journal vide à la fin:

final int chunkSize = 2048;
for (int i = 0; i < s.length(); i += chunkSize) {
    Log.d(TAG, s.substring(i, Math.min(s.length(), i + chunkSize)));
}
LarsH
la source
Merci. Plus de 3000 symboles ne sont pas recommandés, je les utilise.
CoolMind
9

Voici comment OkHttp avec HttpLoggingInterceptor le fait:

public void log(String message) {
  // Split by line, then ensure each line can fit into Log's maximum length.
  for (int i = 0, length = message.length(); i < length; i++) {
    int newline = message.indexOf('\n', i);
    newline = newline != -1 ? newline : length;
    do {
      int end = Math.min(newline, i + MAX_LOG_LENGTH);
      Log.d("OkHttp", message.substring(i, end));
      i = end;
    } while (i < newline);
  }
}

MAX_LOG_LENGTH est de 4000.

Ici, il utilise Log.d (débogage) et la balise "OkHttp" codée en dur.

Il divise le journal aux nouvelles lignes ou lorsqu'il atteint la longueur maximale.

Cette classe ci-dessous est une classe d'aide que vous pouvez utiliser (si vous avez le support lambda, lancez Jack & Jill ou retrolambda) pour faire la même chose que OkHttp fait sur n'importe quel journal:

/**
 * Help printing logs splitting text on new line and creating multiple logs for too long texts
 */

public class LogHelper {

    private static final int MAX_LOG_LENGTH = 4000;

    public static void v(@NonNull String tag, @Nullable String message) {
        log(message, line -> Log.v(tag, line));
    }

    public static void d(@NonNull String tag, @Nullable String message) {
        log(message, line -> Log.d(tag, line));
    }

    public static void i(@NonNull String tag, @Nullable String message) {
        log(message, line -> Log.i(tag, line));
    }

    public static void w(@NonNull String tag, @Nullable String message) {
        log(message, line -> Log.w(tag, line));
    }

    public static void e(@NonNull String tag, @Nullable String message) {
        log(message, line -> Log.e(tag, line));
    }

    public static void v(@NonNull String tag, @Nullable String message, @Nullable Throwable throwable) {
        log(message, throwable, line -> Log.v(tag, line));
    }

    public static void d(@NonNull String tag, @Nullable String message, @Nullable Throwable throwable) {
        log(message, throwable, line -> Log.d(tag, line));
    }

    public static void i(@NonNull String tag, @Nullable String message, @Nullable Throwable throwable) {
        log(message, throwable, line -> Log.i(tag, line));
    }

    public static void w(@NonNull String tag, @Nullable String message, @Nullable Throwable throwable) {
        log(message, throwable, line -> Log.w(tag, line));
    }

    public static void e(@NonNull String tag, @Nullable String message, @Nullable Throwable throwable) {
        log(message, throwable, line -> Log.e(tag, line));
    }

    private static void log(@Nullable String message, @NonNull LogCB callback) {
        if (message == null) {
            callback.log("null");
            return;
        }
        // Split by line, then ensure each line can fit into Log's maximum length.
        for (int i = 0, length = message.length(); i < length; i++) {
            int newline = message.indexOf('\n', i);
            newline = newline != -1 ? newline : length;
            do {
                int end = Math.min(newline, i + MAX_LOG_LENGTH);
                callback.log(message.substring(i, end));
                i = end;
            } while (i < newline);
        }
    }

    private static void log(@Nullable String message, @Nullable Throwable throwable, @NonNull LogCB callback) {
        if (throwable == null) {
            log(message, callback);
            return;
        }
        if (message != null) {
            log(message + "\n" + Log.getStackTraceString(throwable), callback);
        } else {
            log(Log.getStackTraceString(throwable), callback);
        }
    }

    private interface LogCB {
        void log(@NonNull String message);
    }
}
Daniele Segato
la source
Je le cherchais moi-même dans leur code mais je ne pouvais pas le trouver. Je vous remercie.
bugs se produisent
8

Essayez ce morceau de code pour afficher un long message dans logcat.

public void logLargeString(String str) {
    if(str.length() > 3000) {
        Log.i(TAG, str.substring(0, 3000));
        logLargeString(str.substring(3000));
    } else {
        Log.i(TAG, str); // continuation
    }
}
mani
la source
6
lorsqu'une simple boucle sera suffisante, pourquoi utiliser la récursivité.
pellucide
3
Je suis un fan de la récursivité car je trouve que la facilité de lecture et la réutilisation du code sont excellentes. Cependant, cette récursivité de fin de queue peut rapidement créer des cadres de pile si votre compilateur ne les optimise pas (ce que je ne crois pas que le studio Android fasse). Cela signifie que si vous avez un message substantiellement long qui provoque un pluribus d'appels récursifs, vous pouvez facilement créer une StackOverflowError.
Luc
3

Afin de ne pas minimiser la division des lignes entre les messages de journal, je prends la grande chaîne et je consigne chaque ligne séparément.

void logMultilineString(String data) {
    for (String line : data.split("\n")) {
        logLargeString(line);
    }
}

void logLargeString(String data) {
    final int CHUNK_SIZE = 4076;  // Typical max logcat payload.
    int offset = 0;
    while (offset + CHUNK_SIZE <= data.length()) {
        Log.d(TAG, data.substring(offset, offset += CHUNK_SIZE));
    }
    if (offset < data.length()) {
        Log.d(TAG, data.substring(offset));
    }
}
vonWippersnap
la source
1

Voici une version Kotlin pour la réponse @spatulamania (en particulier pour les paresseux / intelligents):

val maxLogSize = 1000
val stringLength = yourString.length
for (i in 0..stringLength / maxLogSize) {
    val start = i * maxLogSize
    var end = (i + 1) * maxLogSize
    end = if (end > yourString.length) yourString.length else end
    Log.v("YOURTAG", yourString.substring(start, end))
}
Filipe Brito
la source
1

Je considère que Timber est une bonne option pour ce problème. Timber divise et imprime automatiquement des morceaux de message dans logcat.

https://github.com/JakeWharton/timber

Vous pouvez voir l'implémentation de la méthode de journalisation dans la classe statique timber.log.Timber.DebugTree.

Jaelson Wagner
la source
0

si print chaîne json, peut utiliser le code ci-dessous

    @JvmStatic
    fun j(level: Int, tag: String? = null, msg: String) {
        if (debug) {
            if (TextUtils.isEmpty(msg)) {
                p(level, tag, msg)
            } else {
                val message: String
                message = try {
                    when {
                        msg.startsWith("{") -> {
                            val jsonObject = JSONObject(msg)
                            jsonObject.toString(4)
                        }
                        msg.startsWith("[") -> {
                            val jsonArray = JSONArray(msg)
                            jsonArray.toString(4)
                        }
                        else -> msg
                    }
                } catch (e: JSONException) {
                    e.printStackTrace()
                    msg
                }
                p(level, tag, "╔═══════════════════════════════════════════════════════════════════════════════════════", false)
                val lines = message.split(LINE_SEPARATOR.toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
                for (line in lines) {
                    p(level, tag, "║ $line", false)
                }
                p(level, tag, "╚═══════════════════════════════════════════════════════════════════════════════════════", false)
            }
        }
    }

code complet

CXLogUtil.j ("json-tag", "{}")

aperçu du résultat

Michael Mao
la source
-2

Pour une solution simple, utilisez l' option Utiliser une enveloppe souple ci-dessous, le point d'attache no 4, les options peuvent vous aider.

Mohit Suthar
la source