• Next, the createMessage method:
    private String createMessage(String message, Object... args) { 
      return args == null || args.length == 0 ? message : String.format(message, args);
    }Copy the code

    I (message, args) does not write args, which is null, and can be printed directly as a message. Also mentioned in the blogger’s last article:

    Logger. I (" blogger only % D this year, English name is %s", 16, "Jerry");Copy the code

    String.format (String. XML) : String. Format (String.

  • For the most part, we have processed the tag, print level, and print message, and now it is time to print:
    @Override public synchronized void log(int priority, String tag, String message, Throwable Throwable) {if (settings.getLogLevel() == loglevel.none) {return; } // If (throwable! Throwable! = null && message ! = null) { message += " : " + Helper.getStackTraceString(throwable); } if (throwable ! = null && message == null) { message = Helper.getStackTraceString(throwable); } if (message == null) { message = "No message/exception is set"; } int methodCount = getMethodCount(); If (helper. isEmpty(message)) {message = "Empty/NULL log message"; } // Print the top border of the log body logTopBorder(priority, tag); // Prints the header content of the log body logHeaderContent(priority, tag, methodCount); //get bytes of message with system's default charset (which is UTF-8 for Android) byte[] bytes = message.getBytes(); int length = bytes.length; If (length <= CHUNK_SIZE) {if (methodCount > 0) {// If the number of methods is greater than 0, print the divider logDivider(priority, tag); } // Print the message content logContent(priority, tag, message); // Print the bottom border of the log body logBottomBorder(priority, tag); return; } if (methodCount > 0) { logDivider(priority, tag); } for (int i = 0; i < length; i += CHUNK_SIZE) { int count = Math.min(length - i, CHUNK_SIZE); //create a new String with system's default charset (which is UTF-8 for Android) logContent(priority, tag, new String(bytes, i, count)); } logBottomBorder(priority, tag); }Copy the code

    Let’s focus on the logHeaderContent method and the logContent method:

    @SuppressWarnings("StringBufferReplaceableByString") private void logHeaderContent(int logType, String tag, Int methodCount) {// Get the current thread stack trace element array // (which stores some information about methods called by the virtual machine: StackTraceElement[] trace = thread.currentThread ().getStackTrace(); / / determine whether a library configuration displays thread information if (Settings) isShowThreadInfo ()) {/ / get the name of the current thread, and print it out, Then print the divider logChunk(logType, tag, HORIZONTAL_DOUBLE_LINE + "Thread: "+ thread.currentThread ().getName()); logDivider(logType, tag); } String level = ""; Int stackOffset = getStackOffset(trace) + settings.getmethodoffSet (); //corresponding method count with the current stack may exceeds the stack trace. Trims the count // The number of methods that print traces exceeds the number of methods that the current thread can trace, the total number of trace methods minus the offset (the number of methods deducted from the call log), If (methodCount + stackOffset > trace.length) {methodCount = trace.length-stackoffset-1; } for (int i = methodCount; i > 0; i--) { int stackIndex = i + stackOffset; if (stackIndex >= trace.length) { continue; } string StringBuilder Builder = new StringBuilder(); Builder.append ("║ ").appEnd (level).append(getSimpleClassName(trace[stackIndex].getClassName()))).append(".") .appEnd (trace[stackIndex].getMethodName()) // The method name traced.appEnd (" ").append(" (")) .appEnd (trace[stackIndex].getFilename ()) // The name of the file where the method resides.append(":").append(trace[stackIndex].getLinenumber ()) // The line number in the file .append(")"); level += " "; // Print the header information logChunk(logType, tag, builder.tostring ()); }}Copy the code



    Method part of the stitching effect


    Now look at the logContent method:

    Private void logContent(int logType, String tag, String chunk) {// String[] lines = chunk.split(system.getProperty ("line.separator")); String[] lines = chunk.split(system.getProperty ("line.separator")); For (String line: lines) {logChunk(logType, tag, HORIZONTAL_DOUBLE_LINE + "" + line); }}Copy the code

    As shown in the figure above, the content is an array of strings. There is no line break in the array itself, so there is no need for line breaks. The printed effect is just one line, but json and XML formats have line breaks.




    Beautiful JSON display format


    The logChunk method is the same as the logChunk method.

    Private void logChunk(int logType, String tag, String chunk) {private void logChunk(int logType, String tag, String chunk) {// finalTag = formatTag(tag); Switch (logType) {case ERROR: settings.getLogAdapter().e(finalTag, chunk); break; case INFO: settings.getLogAdapter().i(finalTag, chunk); break; case VERBOSE: settings.getLogAdapter().v(finalTag, chunk); break; case WARN: settings.getLogAdapter().w(finalTag, chunk); break; case ASSERT: settings.getLogAdapter().wtf(finalTag, chunk); break; case DEBUG: // Fall through, log debug by default default: settings.getLogAdapter().d(finalTag, chunk); break; }}Copy the code

    GetLogAdapter () : settings.getLogAdapter() : settings.java

    Public LogAdapter getLogAdapter() {if (LogAdapter == null) {AndroidLogAdapter LogAdapter = new AndroidLogAdapter(); } return logAdapter; }Copy the code

    Find the AndroidLogAdapter class: