Android的Log包裝輸出

在Android開發(fā)過程中經(jīng)常使用Log打印一些調(diào)試的信息,比如:

Log.d(TAG, "xxxxx");

但是,每一個(gè)類都要定義一個(gè)TAG,一般TAG等于類名本身,比較繁瑣.更重要的是,每次還要帶上這個(gè)參數(shù).如果打印的信息比較多或者一個(gè)類的代碼數(shù)量比較長(zhǎng)時(shí),不太方便查找Log的位置.那么有沒有一種方法,解決上面的問題呢?

問題分析

  1. 每個(gè)類的TAG等于類名,那么能不能自己去尋找類名呢?
  2. 能不能找到打印log所在的位置呢?

答案是肯定的!在Java中可以使用Throwable類獲取棧的信息.

StackTraceElement[] elements = new Throwable().getStackTrace();
String className = elements[1].getFileName();
String methodName = elements[1].getMethodName();
int lineNumber = elements[1].getLineNumber();

通過此方法可以獲取類名,方法名,行號(hào)信息.獲取到信息后還需在包裝一下,因?yàn)槭荄ebug時(shí)的Log就取名DLog吧.
那么Dlog中肯定要有一個(gè)Log的實(shí)例,還要與Log方法同名的方法,比如v(),d(),e(),w(),i()等.如下所示:

public class DLog {
    private static String className;            //所在的類名
    private static String methodName;           //所在的方法名
    private static int lineNumber;              //所在行號(hào)

    /**
     * 私有化構(gòu)造器
     */
    private DLog() {}

    /**
     * 是否處于調(diào)試模式
     */
    public static boolean isDebuggable() {
        return BuildConfig.DEBUG;
    }

    /**
     * 創(chuàng)建Log信息
     */
    private static String createLog(String log) {

        StringBuffer buffer = new StringBuffer();
        buffer.append("[");
        buffer.append(methodName);
        buffer.append(":");
        buffer.append(lineNumber);
        buffer.append("]");
        buffer.append(log);

        return buffer.toString();
    }

    /**
     * 獲取類名,方法名,行號(hào)
     */
    private static void getMethodNames(StackTraceElement[] sElements) {
        className = sElements[1].getFileName();
        methodName = sElements[1].getMethodName();
        lineNumber = sElements[1].getLineNumber();
    }
    
    public static void v(String message) {
        if (!isDebuggable()) {
            return;
        }

        getMethodNames(new Throwable().getStackTrace());
        Log.v(className, createLog(message));
    }

    public static void d(String message) {
        if (!isDebuggable()) {
            return;
        }


        getMethodNames(new Throwable().getStackTrace());
        Log.d(className, createLog(message));
    }

    public static void i(String message) {
        if (!isDebuggable()) {
            return;
        }

        getMethodNames(new Throwable().getStackTrace());
        Log.i(className, createLog(message));
    }

    public static void w(String message) {
        if (!isDebuggable()) {
            return;
        }

        getMethodNames(new Throwable().getStackTrace());
        Log.w(className, createLog(message));
    }
    
    public static void e(String message) {
        if (!isDebuggable()) {
            return;
        }

        getMethodNames(new Throwable().getStackTrace());
        Log.e(className, createLog(message));
    }
}

這樣好了,即能自己找到類名,又能打印出Log信息所在的位置.且慢,還有一個(gè)問題:

如果一個(gè)項(xiàng)目中使用了很多Log輸出,項(xiàng)目結(jié)束時(shí)又不允許在打印這些信息怎么辦?難道要一個(gè)一個(gè)刪除?

一個(gè)一個(gè)刪除太麻煩了,誰讓我們都想偷懶呢!為何我們不在上面的那個(gè)類加個(gè)控制,不想輸出可以一鍵屏蔽多好呀.

Log中的信息是有類別的,我們可以給每個(gè)類別分個(gè)序號(hào),在來一個(gè)控制序號(hào)的級(jí)別,這樣就可以控制顯示的類別,

/**
 * 包裝后的Log輸出,可控制顯示哪些級(jí)別的LOG
 * @author Administrator
 *
 */
public class DLog {
    private static String className;            //所在的類名
    private static String methodName;           //所在的方法名
    private static int lineNumber;              //所在行號(hào)
    
    public static final int VERBOSE = 1;          //顯示Verbose及以上的Log
    public static final int DEBUG = 2;          //顯示Debug及以上的Log
    public static final int INFO = 3;           //顯示Info及以上的Log
    public static final int WARN = 4;           //顯示W(wǎng)arn及以上的Log
    public static final int ERROR = 5;          //顯示Error及以上的Log
    public static final int NOTHING = 6;        //全部不顯示
    
    public static final int LEVEL = VERBOSE;    //控制顯示的級(jí)別

    private DLog() {
    }

    public static boolean isDebuggable() {
        return BuildConfig.DEBUG;
    }

    private static String createLog(String log) {

        StringBuffer buffer = new StringBuffer();
        buffer.append("[");
        buffer.append(methodName);
        buffer.append(":");
        buffer.append(lineNumber);
        buffer.append("]");
        buffer.append(log);

        return buffer.toString();
    }

    private static void getMethodNames(StackTraceElement[] sElements) {
        className = sElements[1].getFileName();
        methodName = sElements[1].getMethodName();
        lineNumber = sElements[1].getLineNumber();
    }
    
    public static void v(String message) {
        if (!isDebuggable()) {
            return;
        }

        if (LEVEL <= VERBOSE) {
            getMethodNames(new Throwable().getStackTrace());
            Log.v(className, createLog(message));
        }
    }

    public static void d(String message) {
        if (!isDebuggable()) {
            return;
        }

        if (LEVEL <= DEBUG) {
            getMethodNames(new Throwable().getStackTrace());
            Log.d(className, createLog(message));
        }
    }

    public static void i(String message) {
        if (!isDebuggable()) {
            return;
        }

        if (LEVEL <= INFO) {
            getMethodNames(new Throwable().getStackTrace());
            Log.i(className, createLog(message));
        }
    }

    public static void w(String message) {
        if (!isDebuggable()) {
            return;
        }

        if (LEVEL <= WARN) {
            getMethodNames(new Throwable().getStackTrace());
            Log.w(className, createLog(message));
        }
    }
    
    public static void e(String message) {
        if (!isDebuggable()) {
            return;
        }

        if (LEVEL <= ERROR) {
            getMethodNames(new Throwable().getStackTrace());
            Log.e(className, createLog(message));
        }
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,814評(píng)論 25 708
  • 國(guó)家電網(wǎng)公司企業(yè)標(biāo)準(zhǔn)(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報(bào)批稿:20170802 前言: 排版 ...
    庭說閱讀 11,081評(píng)論 6 13
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,837評(píng)論 18 139
  • 《裕語言》速成開發(fā)手冊(cè)3.0 官方用戶交流:iApp開發(fā)交流(1) 239547050iApp開發(fā)交流(2) 10...
    葉染柒丶閱讀 27,557評(píng)論 5 19
  • 感恩清靜的每一天,干凈平和,充滿著希望和祝福。憧憬著美好的未來我們一起在國(guó)外的66號(hào)公路相擁的情景,想想都美好。 ...
    棋心118閱讀 179評(píng)論 0 0