Estoy tratando de mostrar un mensaje largo en logcat. Si el mensaje tiene más de 1000 caracteres, se rompe.
¿Cuál es el mecanismo para mostrar todos los caracteres de mensaje largo en logcat?
Estoy tratando de mostrar un mensaje largo en logcat. Si el mensaje tiene más de 1000 caracteres, se rompe.
¿Cuál es el mecanismo para mostrar todos los caracteres de mensaje largo en logcat?
Respuestas:
Si logcat limita la longitud a 1000, puede dividir la cadena que desea registrar con String.subString () y registrarla en partes. Por ejemplo:
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));
}
veryLongString.length()
es un múltiplo de maxLogSize
. Quizás cambie el <=
a <
.
Como continuación de la respuesta de la espátulamania, escribí una clase contenedora que se encarga de esto por ti. Solo necesita cambiar la importación y registrará todo
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));
}
}
}
Esto se basa en la respuesta de Spatulamania, es un poco más conciso y no agregará un mensaje de registro vacío al final:
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)));
}
Así es como lo hace OkHttp con HttpLoggingInterceptor:
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
es 4000.
Aquí usa Log.d (depuración) y la etiqueta "OkHttp" codificada.
Divide el registro en nuevas líneas o cuando alcanza la longitud máxima.
Esta clase a continuación es una clase auxiliar que puede usar (si tiene soporte lambda, tire Jack & Jill o retrolambda) para hacer lo mismo que OkHttp hace en cualquier registro:
/**
* 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);
}
}
Pruebe este código para mostrar un mensaje largo en 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
}
}
Para no minimizar la división de líneas en los mensajes de registro, tomo la cadena grande y registro cada línea por separado.
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));
}
}
Aquí hay una versión de Kotlin para la respuesta de @spatulamania (especialmente para personas perezosas / inteligentes):
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))
}
Considero que Timber es una buena opción para este problema. Timber divide e imprime automáticamente fragmentos de mensajes en logcat.
https://github.com/JakeWharton/timber
Puede ver la implementación del método de registro en la clase estática timber.log.Timber.DebugTree.
si imprime la cadena json, puede usar el código a continuación
@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)
}
}
}
CXLogUtil.j ("json-tag", "{}")
Para una solución fácil, use la opción Usar envoltura suave en el punto de adjunto no 4 opciones que pueden ayudarlo.