Android日志打印工具類


在做Android開發時,經常需要用到日志打印,我們無法一直將設備連接開發環境使用logcat去抓取日志,這個時候就需要將日志輸出到sdcard中,再將日志文件導出來,在定位一些特殊問題時非常實用。

下面就是一個將日志輸出到sdcard上的Log工具類。

日志樣式如下:

image

該類有以下幾個優點:

  • 可控制日志文件總數。
  • 單日志文件大小可配置,單位為MB。
  • 未使用其他三方庫,使用原生API編寫,可直接導入項目中使用。

要使用該工具類需要申請一下權限:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

日志工具類源碼如下:

import android.util.Log;

import java.io.File;
import java.io.FileWriter;
import java.io.FilenameFilter;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;

public class LogUtil {

    // 日志文件總數
    private static final int LOG_FILE_TOTAL = 10;
    // 單日志文件大小上限 MB
    private static final long LOG_SIZE_MAX = 10;
    // 日志文件輸出文件夾
    private static final String LOG_FILE_PRINT_DIR = "/sdcard/ADAS/log/info/";

    // 文件名格式
    private static final SimpleDateFormat FILE_NAME_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss-SSS");

    private static final Object LOCK = new Object();


    public static final void d(String TAG, String msg) {
        synchronized (LOCK) {
            Log.d(TAG, msg);
            printLog("DEBUG", TAG, msg);
        }
    }

    public static final void i(String TAG, String msg) {
        synchronized (LOCK) {
            Log.i(TAG, msg);
            printLog("INFO ", TAG, msg);
        }
    }

    public static final void w(String TAG, String msg) {
        synchronized (LOCK) {
            Log.i(TAG, msg);
            printLog("WARN ", TAG, msg);
        }
    }

    public static final void e(String TAG, String msg) {
        synchronized (LOCK) {
            Log.i(TAG, msg);
            printLog("ERROR", TAG, msg);
        }
    }

    public static final void error(Exception e) {
        synchronized (LOCK) {
            e.printStackTrace();
            printStackTrace(e);
        }
    }

    private static void printLog(String level, String TAG, String msg) {
        try {
            FileWriter fileWriter = new FileWriter(getFile(), true);
            fileWriter.write(formatLog(level, TAG, msg));
            fileWriter.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void printStackTrace(Exception exception) {
        try {
            StringWriter errorsWriter = new StringWriter();
            exception.printStackTrace(new PrintWriter(errorsWriter));
            FileWriter fileWriter = new FileWriter(getFile(), true);
            fileWriter.write(formatLog("ERROR", "System.err", errorsWriter.toString()));
            fileWriter.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    //格式化日志
    private static String formatLog(String level, String TAG, String msg) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
        StringBuilder builder = new StringBuilder();
        builder.append(dateFormat.format(new Date(System.currentTimeMillis())) + " ");
        builder.append("[" + level + "] ");
        builder.append("[" + TAG + "] ");
        builder.append(msg);
        builder.append("\n");
        return builder.toString();
    }

    // 獲取需要輸出的日志文件
    private static File getFile() {

        // 確認文件夾是否存在
        File fileDir = new File(LOG_FILE_PRINT_DIR);
        if (!fileDir.exists()) {
            fileDir.mkdirs();
        }
        // 獲取文件夾下的日志文件
        File[] fileList = fileDir.listFiles(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                return name.endsWith(".log");
            }
        });
        int fileCount = fileList == null ? 0 : fileList.length;

        // 沒有日志文件時,直接創建新文件
        if (fileCount == 0) {
            return createLogFile();
        }

        // 只有一個日志文件時
        if (fileCount == 1) {
            return isCreateLogFile(fileList[0]);
        }

        // 對日志排序,排序結果為升序
        Arrays.sort(fileList, new Comparator<File>() {
            @Override
            public int compare(File file1, File file2) {
                String file1Name = "";
                String file2Name = "";
                try {
                    file1Name = file1.getName().split(".log")[0];
                    file2Name = file2.getName().split(".log")[0];

                    Date dateFile1 = FILE_NAME_FORMAT.parse(file1Name);
                    Date dateFile2 = FILE_NAME_FORMAT.parse(file2Name);
                    return dateFile1.getTime() < dateFile2.getTime() ? -1 : 1;
                } catch (Exception e) {
                    Log.i("LogUtil", "file1Name:" + file1Name + ",   file2Name:" + file2Name);
                    e.printStackTrace();

                }
                return 0;
            }
        });
        File lastFile = fileList[fileCount - 1];
        // 日志文件未超過最大控制個數
        if (fileCount <= LOG_FILE_TOTAL) {
            return isCreateLogFile(lastFile);
        }

        // 刪除時間最早的一個文件
        fileList[0].delete();
        return isCreateLogFile(lastFile);
    }


    // 確認是否需要創建新日志文件
    private static File isCreateLogFile(File file) {
        // 超過日志文件大小上限,需要創建新日志文件
        if (sizeOf(file) >= LOG_SIZE_MAX) {
            return createLogFile();
        }
        return file;
    }


    // 創建一個新的日志文件
    private static File createLogFile() {
        return new File(LOG_FILE_PRINT_DIR + FILE_NAME_FORMAT.format(new Date(System.currentTimeMillis())) + ".log");
    }

    // 計算文件大小,返回單位 MB
    private static long sizeOf(File file) {
        long length = file.length();
        return length / 1024 / 1024;
    }

}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM