1. 程式人生 > >android除錯log輸出及類似C/C++中的__FILE__、__FUNC__、__LINE__等功能

android除錯log輸出及類似C/C++中的__FILE__、__FUNC__、__LINE__等功能

下面的log記錄方式是隻是自己使用覺得方便的一種形式。

android程式出現問題一般有兩種情況

1、直接崩潰。這個比較好找問題。可以直接通過log的error裡面去定位到出錯的地方。

2、執行結果效果沒有符合預期。這個就需要在程式中增加log進行定位。

android.util.Log常用的方法有以下5個:Log.v() Log.d() Log.i() Log.w() 以及 Log.e() 。根據首字母對應VERBOSE,DEBUG,INFO, WARN,ERROR。同時還要System.out.println()等。如果沒有進行區分和統一使用。有時候也會覺得很亂。

    這些log的區別其實不大,使用那個都可以。只是等級不一樣。在lotcat裡面過濾的形式不一樣而已。

所以通常我只使用了v和e兩種log,其他的log不使用,不想去區分。

    在任何一個public類裡面,我們都會增加一個變數 private static final String TAG = “類名”;並且把這個TAG作為log呼叫的TAG引數。但是不同的類就是不同的TAG。如果VERBOSE這種log不進行過濾的話,很多不是我們應用的log都會打印出來進行干擾。所以log肯定是需要進行過濾的。但是如果通過TAG過濾的話很難區分哪些log是先出現,哪些log是後面出現的。所以希望是統一的TAG。

    一般我們列印的log看有沒有執行某個函式通常是Log.i(TAG,"onCreate")。如果每個函式都這樣打log的話,要頻繁的輸入函式的名字,所以會感覺非常不方便,所以我們需要封裝類似於C/C++中的__FILE__、__FUNC__、__LINE__等功能。

    下面的DBG.java就封裝了上面的功能。比如可以通過DBG.log(TAG,DBG._FUNC_());來看有沒有執行到某個函式。

package com.wyd.music.vo;

import java.text.SimpleDateFormat;
import java.util.Date;
import android.annotation.SuppressLint;
import android.util.Log;

/**
 * 除錯中的日誌輸出以及類似<br>
 * C/C++中的__FILE__、__FUNC__、__LINE__等功能
 * 
 * @author WangYD
 * @time 2015年8月4日
 */
public class DBG {
	public static final String TAG = "DBG";
	public static final boolean D = true;

	public static void log(String tag, String msg) {
		if (D) {
			Log.i(TAG, tag + "-> " + msg); //統一TAG
			Log.i(tag, msg);//有時候也需要進一步過濾某個類的TAG
		}
	}

	public static void log(String tag, String msg, Exception e) {
		if (D) {
			Log.e(TAG, tag + "-> " + msg, e);
			Log.e(tag, msg, e);
		}
	}
	/**
	 * 當前檔名
	 * 
	 * @return
	 */
	public static String _FILE_() {
		if (!D)
			return "release";
		StackTraceElement traceElement = ((new Exception()).getStackTrace())[1];
		return traceElement.getFileName();
	}

	/**
	 * 當前方法名
	 * 
	 * @return
	 */
	public static String _FUNC_() {
		if (!D)
			return "release";
		StackTraceElement traceElement = ((new Exception()).getStackTrace())[1];
		return traceElement.getMethodName();
	}

	/**
	 * 當前行號
	 * 
	 * @return
	 */
	public static int _LINE_() {
		if (!D)
			return 0;
		StackTraceElement traceElement = ((new Exception()).getStackTrace())[1];
		return traceElement.getLineNumber();
	}

	/**
	 * 當前時間
	 * 
	 * @return
	 */
	@SuppressLint("SimpleDateFormat")
	public static String _TIME_() {
		if (!D)
			return "release";
		Date now = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
		return sdf.format(now);
	}

	public static void main(String[] args) {
		System.out.println(DBG._FILE_());
		System.out.println(DBG._FUNC_());
		System.out.println(DBG._LINE_());
		System.out.println(DBG._TIME_());
		System.out.println(DBG.getFileLineMethod());
		System.out.println("&&&&&&&&&&&&");

		StackTraceElement traceElement = ((new Exception()).getStackTrace())[0];
		System.out.println(traceElement.getClassName());
		System.out.println(traceElement.getFileName());
		System.out.println(traceElement.getLineNumber());
		System.out.println(traceElement.getMethodName());
		System.out.println("&&&&&&&&&&&&");
		XXXX();

	}

	public static void XXXX() {
		YYYY();
	}

	public static void YYYY() {
		ZZZZ();
	}

	public static void ZZZZ() {
		StackTraceElement[] traceElement = ((new Exception()).getStackTrace());
		for (int i = 0; i < traceElement.length; i++) {
			System.out.println(traceElement[i].getClassName());
			System.out.println(traceElement[i].getFileName());
			System.out.println(traceElement[i].getLineNumber());
			System.out.println(traceElement[i].getMethodName());
			System.out.println("***************");
		}
	}

}

上面的main函式是在java裡面進行測試一段程式碼。主要是想看 StackTraceElement 這個類是什麼。初步理解就是執行的軌跡,呼叫的軌跡吧。XXXX(),YYYY(),ZZZZ()等函式的巢狀。巢狀的越多StackTraceElement返回的陣列長度越大。因為一般我們在我的函式裡面呼叫了DBG._FUN_();在_FUN_裡面呼叫了((new Exception()).getStackTrace()); 所以返回的StackTraceElement[0]是_FUN_裡面的

StackTraceElement[1]則是呼叫DBG._FUN_()裡面的。

上面main打印出來如下:行數其實是呼叫到((new Exception()).getStackTrace());的行數

DBG.java
main
56
2015-08-04 11:17:38.264
[DBG.java | 58 | main]
&&&&&&&&&&&&
com.pax.DBG
DBG.java
61
main
&&&&&&&&&&&&
com.pax.DBG
DBG.java
76
ZZZZ
***************
com.pax.DBG
DBG.java
87
YYYY
***************
com.pax.DBG
DBG.java
72
XXXX
***************
com.pax.DBG
DBG.java
67
main
***************

相關推薦

android除錯log輸出類似C/C++__FILE____FUNC____LINE__功能

下面的log記錄方式是隻是自己使用覺得方便的一種形式。 android程式出現問題一般有兩種情況 1、直接崩潰。這個比較好找問題。可以直接通過log的error裡面去定位到出錯的地方。 2、執行結果效果沒有符合預期。這個就需要在程式中增加log進行定位。 android.u

JNI學習二之(C原始碼Log輸出常見錯誤)

瞭解jni JNI 即Java Native Interface ,Java本機介面。可以實現Java和C/C++之間的相互呼叫。 為什麼使用JNI? 擴充套件了Java虛擬機器的能力,C語言可以進行驅動開發,比如wifi共享熱點的驅動 Native c

Android平臺Log輸出規範

1、 目的: 為了規範軟體工程師在android程式碼編寫過程中輸出Log的行為,使得釋出的產品中列印的Log是必須的,列印的Log的級別是能真實反映此Log對應的級別,標籤、Log內容具有很好的可讀性。 2、 適用範圍 android平臺java、c++、c程式碼編寫。

androidLog輸出

Java程式碼 package com.zijun;       import android.app.Activity;    import android.content.Context;    import android.graphics.Canvas;    import android.os.Bu

C語言 有符號數無符號數整數溢出 (轉)

alt 原因 () tar sig 重新 detail copyto 想象 [cpp] view plain copy print? #include<stdio.h> void main() { int l=-1; unsigned

C++ 語言的重載內聯缺省參數隱式轉換機制展現了很多優點

str 指針 div sin code console etc 聲明 隱患 C++ 語言中的重載、內聯、缺省參數、隱式轉換等機制展現了很多優點,但是這些 優點的背後都隱藏著一些隱患。正如人們的飲食,少食和暴食都不可取,應當恰到好處。 我們要辨證地看待 C++的新機制,應該恰

關於C語言的陣列指標指標陣列以及二級指標

概念解釋 陣列指標:首先它是一個指標,它指向一個數組,即指向陣列的指標;在32 位系統下永遠是佔4 個位元組,至於它指向的陣列佔多少位元組,不知道。陣列指標指向的是陣列中的一個具體元素,而不是整個陣列,所以陣列指標的型別和陣列元素的型別有關。 指標陣列:首先

C語言利用共用體結構體位域實現位操作

編寫過51(MCU)程式的同學都知道51架構的MCU支援位操作,這是一個很方便的特性,在讀取/修改暫存器某位的值時非常方便快捷。但其他架構的MCU大多都不支援該特性,即不支援位操作,所在在對暫存器中某一位進行操作的時候都是and/or兩個操作共同使用,在編寫程式時非常麻煩。

C語言基本型別charshortintlong型別的取值範圍

        在C語言中,有時候會想知道這些基本型別的取值範圍。用邏輯位操作的方法是可以,比如把整型變數的所有位都賦值1,然後把最高位賦值為0,就可以得到整型的最大值了。         其實,還有一個更簡單的方法獲取這些基本型別的取值範圍。那就是使用系統標頭檔案limi

C++容器勿使用memset,memcpy

當一個數據結構中,包含map表,list表,vactor等容器時,勿使用memset初始化該結構。 否則,會導致該結構資訊不可用。 map表在初始化時,會自動呼叫建構函式,若memset後,那麼建構函式就會被破壞,導致構造失敗,進而導致map表不可用。 切記!切記!

C語言__FILE____LINE__ 巨集的含義

int main(int argc, char *argv[]) {   printf( "file=%s/nline=%s ",__FILE__,__LINE__);   return (0); }

C語言的空指標空指標常量NULL & 0

空指標:NULL還是0 看林銳博士的《高質量C/CPP程式設計》附錄的試卷,對空指標的判斷居然強制要用NULL(如 if(p==NULL) ),後來從這篇文章看到一些東西覺得有點意思。不耐煩看的人看我的歸納:  0、0和數值“零”在指標上下文中不是一回事,0就是空指標,而不一定是“零”  1、用0還

c語言靜態全域性變數靜態區域性變數全域性變數區域性變數巨集

全域性變數: 全域性變數具有全域性作用域。,它只編譯期被始化一次,它不能用變數來初始化。全域性變數只需要在一個原始檔中定義,就可以作用於所有的原始檔。在其他不包含全域性變數定義的原始檔中需要用extern關鍵詞來再次宣告這個全域性變數 區域性變數: 區域性變數只有區域性

Android 4.2.2會有哪些改進?快速設定Google Play下載功能

從2013年2月12日開始已經有部分 Nexus 裝置陸續收到了 Android 4.2.2 的更新提示,那麼除了「系統表現和穩定性」之外這次升級到底有哪些具體的內容呢?Android Police 在仔細看過 Google 的變更日誌後為我們找到了一些答案。新版中的 Google Play 在下

Android自定義View來實現解析lrc歌詞同步滾動上下拖動縮放歌詞功能

http://blog.csdn.net/ouyang_peng/article/details/50813419 前言 最近有個專案有關於播放音樂時候,關於歌詞有以下幾個功能:  1、實現歌詞同步滾動的功能,即歌曲播放到哪句

實現Android Studio JNI開發C/C++使用__android_log_print輸出Log

Android Studio的Android.mk是自動生成的,就算修改也是沒用了,實際Android Studio的Android.mk是根據gradle檔案生成的,那麼就需要修改gradle檔案。如果不修改gradle,直接使用__android_log_print就會報錯Error:(36) undef

輸出成績不及格的學生的學號成績(C語言)

#include <stdio.h> #include <stdlib.h> int main(){ float score[][4]={{60,70,80,90},{56,89,67,88},{34,78,90,66}}; float *search(float

c#的以文字形式輸出輸入的程式碼

輸出方法: 格式一: string path_AA4 = "E:/實驗資料晶/gaocgaizs.txt";   //顯示高程的改正數                     if (File.Exists(path_AA4))                      

C++11vector的emplace_back用法輸入輸出操作符的過載

#include <vector> #include <iostream> #include <string> using namespace std; struc

android studio 3.2 使用cmake在jni生成使用C/C++靜態庫

關於cmake jni的基本教程可以看我另外一篇部落格 關於使用動態庫可以看我的另外一篇部落格。 在看本篇之前,最好先看這篇動態庫的,一些比較基本的操作,都在這裡面。本篇不會講的很細。 總體思路 1.本教程是在Android studio中利用cmake來生成