<返回更多

Android logcat日志封装

2021-12-22    YuCoding
加入收藏

Android logcat日志封装

logcat痛点

在Android开发中使用logcat非常频繁,logcat能帮我们定位问题,但是在日常使用中发现每次使用都需要传递tag,并且会遇到输出频率很高的log,在多人混合开发的场景下,不过滤很难找到自己打的log,调试别人代码时看不懂他人输出的log。这些问题会影响到整个开发效率,并且无法对整个项目的log进行统一管理。

目的

为了方便管理和规范log输出,增加logcat使用的便捷性封装logcat需要满足以下几点:

1、动态管理日志输出

2、使用便捷,只需关注需要输出的massage即可

3、日志信息显示齐全,方便定位与统一

日志输出开关

通过广播及系统属性控制日志的开关,通过注册LOG_SWITCH = "android.App.all.log" 广播,用来控制所有app日志开关,方便多app统一管理,另外通过注册包名后缀+".log"广播(如包名为:com.yxd.logtest,则action为:logtest.log),来控制当前app的日志开关,同时还将开关值存入到系统属性中,以免退出后需重新打开。

通过adb模拟发送广播,实现开关控制,adb命令:adb shell am broadcast -a android.app.all.log --ei status 1

    public static void init(Context context) {
        if (sContext != null){
            return;
        }
        IntentFilter intentFilter = new IntentFilter();
        //系统属性名称不可超过32字符,所以使用包名最后一段+.log 来做属性名
        String[] strings = context.getPackageName().split("\.");
        intentFilter.addAction(strings[strings.length - 1] + ".log");
        intentFilter.addAction(LOG_SWITCH);
        context.registerReceiver(new LogSwitchReceiver(), intentFilter);
        String allLog = SystemProperties.get(LOG_SWITCH);
        String thisLog = SystemProperties.get(strings[strings.length - 1] + ".log");
        if ((!thisLog.isEmpty() && "1".equals(thisLog)) || (!allLog.isEmpty() && "1".equals(allLog))) {
            HQLog.SWITCH = true;
        }
        sContext = context;
    }
    static class LogSwitchReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            int status = intent.getIntExtra(LOG_STATUS, 0);
            Log.d("LogUtils", "LogSwitchReceiver action: " + intent.getAction() + "  status: " + status);
            SystemProperties.set(intent.getAction(), String.valueOf(status));
            HQLog.SWITCH = status == 1;
        }
    }

如果为debug版本,则默认打开日志输出

public static boolean SWITCH = BuildConfig.DEBUG;

输出格式

为了方便使用及定位,输出时需要将类名及行数显示,且在logcat上点击该行可以直接定位到对应输出代码,类似crash报错日志,点击蓝色字体即可跳转至输出行

Android logcat日志封装

 

具体实现如下:

    public static void e(String message) {
        if (SWITCH) {
            Log.e(getTag(), message);
        }
    }

    private static String getTag() {
        StackTraceElement[] traceElements = Thread.currentThread().getStackTrace();
        String tag = null;
        if (traceElements != null && traceElements.length > 4) {
            StackTraceElement traceElement = traceElements[4];
            tag = "(" + traceElement.getFileName() + ":" + traceElement.getLineNumber() + ")" + traceElement.getMethodName();
        } else {
            tag = "ULog";
        }
        return tag;

完整代码

使用时需在application里面init一下

public class MyApplication extends Application {

    private static Context mContext;

    @Override
    public void onCreate() {
        super.onCreate();
        mContext = this;
        LogUtils.init(this);
        AppInfo.initContext(this);
    }

    public static Context getApplication(){
        return mContext;
    }
}

 

public class LogUtils {
    public static String LOG_SWITCH = "android.app.all.log";
    //log开关状态 0关 1开
    public static String LOG_STATUS = "status";
    @SuppressLint("StaticFieldLeak")
    private static Context sContext;
    private static LogSwitchReceiver sLogSwitchReceiver = new LogSwitchReceiver();

    public static void init(Context context) {
        if (sContext != null){
            return;
        }
        IntentFilter intentFilter = new IntentFilter();
        //系统属性名称不可超过32字符,所以使用包名最后一段+.log 来做属性名
        String[] strings = context.getPackageName().split("\.");
        intentFilter.addAction(strings[strings.length - 1] + ".log");
        intentFilter.addAction(LOG_SWITCH);
        context.registerReceiver(new LogSwitchReceiver(), intentFilter);
        String allLog = SystemProperties.get(LOG_SWITCH);
        String thisLog = SystemProperties.get(strings[strings.length - 1] + ".log");
        if ((!thisLog.isEmpty() && "1".equals(thisLog)) || (!allLog.isEmpty() && "1".equals(allLog))) {
            ULog.SWITCH = true;
        }
        sContext = context;
    }

    public static void release() {
        if (sContext != null && sLogSwitchReceiver != null) {
            sContext.unregisterReceiver(sLogSwitchReceiver);
        }
    }

    static class LogSwitchReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            int status = intent.getIntExtra(LOG_STATUS, 0);
            Log.d("LogUtils", "LogSwitchReceiver action: " + intent.getAction() + "  status: " + status);
            SystemProperties.set(intent.getAction(), String.valueOf(status));
            ULog.SWITCH = status == 1;
        }
    }
}
public class ULog {

    public static boolean SWITCH = BuildConfig.DEBUG;

    public static void v(String message) {
        if (SWITCH) {
            Log.v(getTag(), message);
        }
    }

    public static void d(String message) {
        if (SWITCH) {
            Log.d(getTag(), message);
        }
    }

    public static void i(String message) {
        if (SWITCH) {
            Log.i(getTag(), message);
        }
    }

    public static void w(String message) {
        if (SWITCH) {
            Log.w(getTag(), message);
        }
    }

    public static void e(String message) {
        if (SWITCH) {
            Log.e(getTag(), message);
        }
    }

    public static void getStackTraceString(Throwable tr) {
        if (SWITCH) {
            Log.getStackTraceString(tr);
        }
    }

    private static String getTag() {
        StackTraceElement[] traceElements = Thread.currentThread().getStackTrace();
        String tag = null;
        if (traceElements != null && traceElements.length > 4) {
            StackTraceElement traceElement = traceElements[4];
            tag = "(" + traceElement.getFileName() + ":" + traceElement.getLineNumber() + ")" + traceElement.getMethodName();
        } else {
            tag = "ULog";
        }
        return tag;
    }

    private static String generateLogcatText(String msg, int place, String message) {
        return generateLogcatText(Thread.currentThread().getStackTrace(), msg, place, message);
    }

    private static String generateLogcatText(StackTraceElement[] traceElements, String msg, int place, String message) {
        try {
            StringBuilder taskName = new StringBuilder();
            if (traceElements != null && traceElements.length > place) {
                StackTraceElement traceElement = traceElements[place];
                taskName.append(traceElement.getMethodName()).append("() : ").append(message);
            }
            return taskName.toString();
        } catch (Throwable throwable) {
            return msg;
        }
    }
}
声明:本站部分内容来自互联网,如有版权侵犯或其他问题请与我们联系,我们将立即删除或处理。
▍相关推荐
更多资讯 >>>