Android日誌列印工具類
阿新 • • 發佈:2020-12-27
在做Android開發時,經常需要用到日誌列印,我們無法一直將裝置連線開發環境使用logcat去抓取日誌,這個時候就需要將日誌輸出到sdcard中,再將日誌檔案匯出來,在定位一些特殊問題時非常實用。
下面就是一個將日誌輸出到sdcard上的Log工具類。
日誌樣式如下:
該類有以下幾個優點:
可控制日誌檔案總數。
單日誌檔案大小可配置,單位為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;
}
}