在實際情況中,用戶的各種神操作有可能把碼農辛辛苦苦寫的代碼搞崩潰掉,那麼如果有用戶的操作日誌,一切問題將迎刃而解,日誌對於碼農來說簡直是定位bug的一件利器.在開發過程中使用Android的Log類打印日誌,並不能將保存日誌下來,所以特意寫了這個日誌工具類,用來保存用戶的操作日誌,以便代碼發生問題時,能夠及時的定位問題.
/**
* Log 工具類
*
* @author CharlesRich
* @email [email protected]
* @mobile 18602438878
* @create 2020-1-29 18:19
*/
public class LogUtils {
/** 可用用於 release 時,統一關閉寫入 Log 到文件*/
public static boolean isWriteLogToFile = SPUtils.getWriteLogFile(BaseApplication.getInstance());
private static String fileName;
private static String className;//類名
private static String methodName;//方法名
private static int lineNumber;//行數
private static long threadId;
private static String threadName;
/**
* 判斷是否可以調試
* @return
*/
public static boolean isDebuggable() {
try {
ApplicationInfo info = BaseApplication.getInstance().getApplicationInfo();
return (info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
} catch (Exception e) {
return false;
}
}
/**
* 獲取文件名、方法名、所在行數
* @param sElements
*/
private static void getMethodNames(StackTraceElement[] sElements){
fileName = sElements[1].getFileName();
className = sElements[1].getFileName();
methodName = sElements[1].getMethodName();
lineNumber = sElements[1].getLineNumber();
threadId = Thread.currentThread().getId();
threadName = Thread.currentThread().getName();
}
/**
* 打印 VERBOSE 信息
*
* @param tag
* @param message
*/
public static void v(String tag, String message) {
if (!isDebuggable()) {
return;
}
getMethodNames(new Throwable().getStackTrace());
Log.v(tag, createLog(message));
if (isWriteLogToFile) {
LogToFileUtils.i(className, createLog(message));
}
}
/**
* 打印 INFO 信息
*
* @param tag
* @param message
*/
public static void i(String tag, String message) {
if (!isDebuggable()) {
return;
}
getMethodNames(new Throwable().getStackTrace());
Log.i(tag, createLog(message));
if (isWriteLogToFile) {
LogToFileUtils.i(className, createLog(message));
}
}
/**
* 打印 DEBUG 信息
*
* @param tag
* @param message
*/
public static void d(String tag, String message) {
if (!isDebuggable()) {
return;
}
getMethodNames(new Throwable().getStackTrace());
Log.d(tag, createLog(message));
if (isWriteLogToFile) {
LogToFileUtils.i(className, createLog(message));
}
}
/**
* 打印 WARN 信息
*
* @param tag
* @param message
*/
public static void w(String tag, String message) {
if (!isDebuggable()) {
return;
}
getMethodNames(new Throwable().getStackTrace());
Log.w(tag, createLog(message));
if (isWriteLogToFile) {
LogToFileUtils.i(className, createLog(message));
}
}
/**
* 打印 ERROR 信息
*
* @param tag
* @param message
*/
public static void e(String tag, String message) {
if (!isDebuggable()) {
return;
}
getMethodNames(new Throwable().getStackTrace());
Log.e(tag, createLog(message));
if (isWriteLogToFile) {
LogToFileUtils.i(className, createLog(message));
}
}
/**
* 輸出 Log 中包含的信息
*
* @param message
* @return Log 中包含的信息
*/
public static String createLog(String message) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("[ ");
stringBuilder.append("threadID=" + threadId).append(", ");
stringBuilder.append("threadName=" + threadName).append(", ");
stringBuilder.append("fileName=" + fileName).append(", ");
stringBuilder.append("className=" + className).append(", ");
stringBuilder.append("methodName=" + methodName).append(", ");
stringBuilder.append("lineNumber=" + lineNumber);
stringBuilder.append(" ] ");
stringBuilder.append(":" + message);
return stringBuilder.toString();
}
}
/**
* 將Log日誌寫入文件中
*
* @author CharlesRich
* @email [email protected]
* @mobile 18602438878
* @create 2019-11-09 16:57
*/
public class LogToFileUtils {
private static String logPath = null;//log日誌存放路徑
private static SimpleDateFormat dateFormatFile = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS", Locale.US);
private static Date date = new Date();
public static String getFilePath() {
String file_dir = "";
/** SD卡是否存在 */
boolean isSDCardExist = Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState());
boolean isRootDirExist = Environment.getExternalStorageDirectory().exists();
if (isSDCardExist && isRootDirExist) {
file_dir = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "LOG_FILE" + File.separator + "log" + File.separator;
} else {
file_dir = BaseApplication.getInstance().getFilesDir().getAbsolutePath() + File.separator + "log" + File.separator;
}
return file_dir;
}
private static final String VERBOSE = "VERBOSE";
private static final String DEBUG = "DEBUG";
private static final String INFO = "INFO";
private static final String WARN = "WARN";
private static final String ERROR = "ERROR";
public static void v(String tag, String msg) {
writeToFile(VERBOSE, tag, msg);
}
public static void d(String tag, String msg) {
writeToFile(DEBUG, tag, msg);
}
public static void i(String tag, String msg) {
writeToFile(INFO, tag, msg);
}
public static void w(String tag, String msg) {
writeToFile(WARN, tag, msg);
}
public static void e(String tag, String msg) {
writeToFile(ERROR, tag, msg);
}
/**
* 將log信息寫入文件中
*
* @param type
* @param tag
* @param msg
*/
private static void writeToFile(String type, String tag, String msg) {
if (null == logPath) {
logPath = getFilePath();
}
String fileName = logPath + "/log_" + dateFormatFile.format(new Date()) + ".log";
StringBuilder sb = new StringBuilder();
File file = new File(logPath);
/** 如果父路徑不存在 */
if (!file.exists()) {
file.mkdirs();//創建父路徑
sb.append("手機廠商:" + SystemUtils.getDeviceBrand() + "\\n");
sb.append("手機型號:" + SystemUtils.getSystemModel() + "\\n");
sb.append("手機版本:" + SystemUtils.getSystemVersion() + "\\n");
}
sb.append(type + " " + dateFormat.format(date) + " ");
sb.append(tag + ": ");
sb.append(msg + "\\n");
FileOutputStream fos = null;
BufferedWriter bw = null;
try {
fos = new FileOutputStream(fileName, true);
bw = new BufferedWriter(new OutputStreamWriter(fos));
bw.write(sb.toString());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bw != null) {
bw.close();//關閉緩衝流
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* Application基類
*
* @author CharlesRich
* @email [email protected]
* @mobile 18602438878
* @create 2020-1-19 12:19
*/
public class BaseApplication extends Application {
private static final String TAG = BaseApplication.class.getSimpleName();
private static BaseApplication mInstance;
private static Handler mHandler = new Handler();
@Override
public void onCreate(){
super.onCreate();
mInstance = this;
}
/**
* 獲取Instance
*
*/
public static BaseApplication getInstance(){
return mInstance;
}
/**
* 獲取Application Context
*
*/
public static Context getAppContext(){
return mInstance != null ? mInstance.getApplicationContext():null;
}
/**
* 在主線程上執行Runnable
*
*/
public static void runOnMainThread(Runnable runnable){
mHandler.post(runnable);
}
}
閱讀更多 CharlesRich 的文章