Cách hiển thị tin nhắn dài trong logcat


99

Tôi đang cố gắng hiển thị thông báo dài trên logcat. Nếu độ dài của tin nhắn hơn 1000 ký tự, nó sẽ bị hỏng.

Cơ chế để hiển thị tất cả các ký tự của tin nhắn dài trong logcat là gì?


6
Tôi nhận được phản hồi từ máy chủ dưới dạng một chuỗi dài.
Vasu

1
Thậm chí sau đó tại sao bạn lại muốn in toàn bộ chuỗi, hãy viết nó vào một tập tin hoặc cơ sở dữ liệu và xem đó - nếu nó để gỡ lỗi
Rahul Choudhary

sao chép chuỗi logcat của bạn và quá khứ vào notpad, bạn có thể thấy toàn bộ chiều dài 1000 của chuỗi.
ilango j

Câu trả lời:


149

Nếu logcat đang giới hạn độ dài ở mức 1000 thì bạn có thể chia chuỗi mà bạn muốn đăng nhập bằng String.subString () và đăng nhập nó thành từng phần. Ví dụ:

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));
}

Nhật ký mèo chỉ in một nửa câu trả lời .. làm sao tôi có thể lấy được độ dài của toàn bộ câu trả lời. bạn nói rằng veryLongString.length () nhưng ở đây in của nó chỉ là một nửa câu trả lời khi tôi in kết quả json trong nhật ký mèo
Vasu

Nhưng trong bảng điều khiển dành cho iphone, tôi nhận được toàn bộ chuỗi phản hồi
Vasu 30/09/11

bạn có thể kiểm tra độ dài của phản hồi bằng cách ghi length () vào nhật ký. Nếu giá trị này không như bạn mong đợi, vấn đề có thể không phải do ghi nhật ký.
spatulamania

3
Không thể tin được là Android lại làm khó nó đến vậy!
Alston

1
Tôi nghĩ rằng mã này sẽ ghi thêm một mục nhật ký trống ở cuối, nếu veryLongString.length()là bội số maxLogSize. Có thể thay đổi <=thành <.
LarsH

29

Để tiếp tục câu trả lời spatulamania, tôi đã viết một lớp wrapper để xử lý điều này cho bạn. Bạn chỉ cần thay đổi nhập và nó sẽ ghi lại mọi thứ

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));
        }
    }

}

23

Điều này được xây dựng dựa trên câu trả lời của spatulamania, ngắn gọn hơn một chút và sẽ không thêm thông báo nhật ký trống vào cuối:

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)));
}

Cảm ơn. Hơn 3000 biểu tượng không được khuyến khích, tôi sử dụng như vậy.
CoolMind

9

Đây là cách OkHttp với HttpLoggingInterceptor làm điều đó:

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 là 4000.

Ở đây nó sử dụng Log.d (gỡ lỗi) và thẻ "OkHttp" được mã hóa cứng.

Nó tách nhật ký theo dòng mới hoặc khi nó đạt đến độ dài tối đa.

Lớp dưới đây là lớp người trợ giúp bạn có thể sử dụng (nếu bạn có hỗ trợ lambda, hãy ném Jack & Jill hoặc retrolambda) để làm điều tương tự OkHttp thực hiện trên bất kỳ nhật ký nào:

/**
 * 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);
    }
}

Tôi đã tự tìm kiếm nó trong mã của họ nhưng không thể tìm thấy nó. Cảm ơn bạn.
Lỗi xảy ra

8

Hãy thử đoạn mã này để hiển thị thông báo dài trong 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
    }
}

6
khi một vòng lặp đơn giản sẽ là đủ, tại sao lại sử dụng đệ quy.
pellucide

3
Tôi là một fan hâm mộ của đệ quy vì tôi thấy khả năng đọc và tái sử dụng mã rất tốt. Tuy nhiên, đệ quy kết thúc đuôi này có thể tạo khung ngăn xếp một cách nhanh chóng nếu trình biên dịch của bạn không tối ưu hóa chúng (điều mà tôi không tin là Android studio làm được). Điều này có nghĩa là nếu bạn có một tin nhắn dài đáng kể gây ra nhiều cuộc gọi đệ quy, bạn có thể dễ dàng tạo StackOverflowError.
Luke

3

Để không giảm thiểu việc tách dòng giữa các thông báo nhật ký, tôi lấy chuỗi lớn và ghi nhật ký từng dòng riêng biệt.

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));
    }
}

1

Đây là phiên bản Kotlin cho câu trả lời @spatulamania (đặc biệt dành cho những người lười biếng / thông minh):

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))
}

1

Tôi coi Timber là một lựa chọn tốt cho vấn đề này. Gỗ tự động chia nhỏ và in các khối tin nhắn trong logcat.

https://github.com/JakeWharton/timber

Bạn có thể thấy việc triển khai phương thức nhật ký trong lớp tĩnh wood.log.Timber.DebugTree.


0

nếu in chuỗi json, có thể sử dụng mã bên dưới

    @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)
            }
        }
    }

mã đầy đủ

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

kết quả xem trước


-2

Để có một giải pháp dễ dàng, hãy sử dụng Tùy chọn bọc mềm trong tùy chọn đính kèm điểm không có 4 bên dưới có thể giúp bạn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.