我正在尝试在logcat上显示长消息。如果消息的长度超过1000个字符,则会被破坏。
在logcat中显示长消息的所有字符的机制是什么?
答案 0 :(得分:128)
如果logcat将长度限制为1000,那么您可以使用String.subString()拆分要记录的字符串并将其记录为碎片。例如:
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));
}
答案 1 :(得分:27)
作为spatulamania的回答,我写了一个包装类来为你处理这个问题。您只需要更改导入,它就会记录所有内容
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));
}
}
}
答案 2 :(得分:15)
这建立在spatulamania的答案之上,有点简洁,并且最后不会添加空的日志消息:
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)));
}
答案 3 :(得分:6)
尝试使用这段代码在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
}
}
答案 4 :(得分:5)
使用HttpLoggingInterceptor的OkHttp就是这样做的:
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
是4000。
这里使用Log.d(debug)和硬编码&#34; OkHttp&#34;标签
它将日志分成换行符或达到最大长度。
下面这个类是一个帮助类,你可以使用(如果你有lambda支持抛出Jack&amp; Jill或者retrolambda)来做OkHttp在任何日志上做的事情:
/**
* 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);
}
}
答案 5 :(得分:2)
为了不尽量减少日志消息中的分割线,我采用大字符串并分别记录每一行。
class Test{
private int someValue = 10;
[RunWhen(10)]
public void MethodA(){
Console.WriteLine("Method A");
}
[RunWhen(100)]
public void MethodB(){
Console.WriteLine("Method B");
}
[RunWhen(1000)]
public void MethodC(){
Console.WriteLine("Method C");
}
}
答案 6 :(得分:1)
以下是@spatulamania answer的Kotlin版本(特别是懒惰/聪明人):
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))
}
答案 7 :(得分:1)
我认为Timber是解决这个问题的好方法。 Timber会在logcat中自动拆分并打印消息块。
https://github.com/JakeWharton/timber
您可以在timber.log.Timber.DebugTree静态类中看到日志方法实现。
答案 8 :(得分:0)
如果打印json字符串,可以使用下面的代码
@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”,“ {}”)
答案 9 :(得分:0)
通过 Kotlin,我们可以使用 stdlib chunked 函数:
fun logUnlimited(tag: String, string: String) {
val maxLogSize = 1000
string.chunked(maxLogSize).forEach { Log.v(tag, it) }
}
答案 10 :(得分:-3)