Android Log的多场景使用
来源:互联网 发布:淘宝虎扑伙伴是真的吗 编辑:程序博客网 时间:2024/05/18 20:31
背景:不同情况下,我们有不同的需求,下面我们总结一下所有的case采用不同的策略。
方案一:
通过一个开关,决定是否输出log,也可以决定是否输出到文件,方便我们调试使用。
package ls.utils;import java.io.PrintWriter;import java.io.StringWriter;import java.io.Writer;import android.text.TextUtils;import android.text.format.DateFormat;import android.util.Log;import com.config.AppConfig;/** * Title: LogUtils.java Description: 日志工具类:开发过程中,日志输出 * * @author song * @date 2014-9-9 下午1:22:55 * @version V1.0 */public class LogUtils {/** * isWrite:用于开关是否吧日志写入txt文件中</p> */private static final boolean isWrite = false;/** * isDebug :是用来控制,是否打印日志 */private static final boolean isDeBug = true;/** * 存放日志文件的所在路径 */private static final String DIRPATH = AppConfig.LOG_DIRPATH;// private static final String DIRPATH = "/log";/** * 存放日志的文本名 */private static final String LOGNAME = AppConfig.LOG_FILENAME;// private static final String LOGNAME = "log.txt";/** * 设置时间的格式 */private static final String INFORMAT = "yyyy-MM-dd HH:mm:ss";/** * VERBOSE日志形式的标识符 */public static final int VERBOSE = 5;/** * DEBUG日志形式的标识符 */public static final int DEBUG = 4;/** * INFO日志形式的标识符 */public static final int INFO = 3;/** * WARN日志形式的标识符 */public static final int WARN = 2;/** * ERROR日志形式的标识符 */public static final int ERROR = 1;/** * 把异常用来输出日志的综合方法 * * @param @param tag 日志标识 * @param @param throwable 抛出的异常 * @param @param type 日志类型 * @return void 返回类型 * @throws */public static void log(String tag, Throwable throwable, int type) {log(tag, exToString(throwable), type);}/** * 用来输出日志的综合方法(文本内容) * * @param @param tag 日志标识 * @param @param msg 要输出的内容 * @param @param type 日志类型 * @return void 返回类型 * @throws */public static void log(String tag, String msg, int type) {switch (type) {case VERBOSE:v(tag, msg);// verbose等级break;case DEBUG:d(tag, msg);// debug等级break;case INFO:i(tag, msg);// info等级break;case WARN:w(tag, msg);// warn等级break;case ERROR:e(tag, msg);// error等级break;default:break;}}/** * verbose等级的日志输出 * * @param tag * 日志标识 * @param msg * 要输出的内容 * @return void 返回类型 * @throws */public static void v(String tag, String msg) {// 是否开启日志输出if (isDeBug) {Log.v(tag, msg);}// 是否将日志写入文件if (isWrite) {write(tag, msg);}}/** * debug等级的日志输出 * * @param tag * 标识 * @param msg * 内容 * @return void 返回类型 * @throws */public static void d(String tag, String msg) {if (isDeBug) {Log.d(tag, msg);}if (isWrite) {write(tag, msg);}}/** * info等级的日志输出 * * @param tag 标识 * @param msg 内容 * @return void 返回类型 * @throws */public static void i(String tag, String msg) {if (isDeBug) {Log.i(tag, msg);}if (isWrite) {write(tag, msg);}}/** * warn等级的日志输出 * * @param tag 标识 * @param msg 内容 * @return void 返回类型 * @throws */public static void w(String tag, String msg) {if (isDeBug) {Log.w(tag, msg);}if (isWrite) {write(tag, msg);}}/** * error等级的日志输出 * * @param tag 标识 * @param msg 内容 * @return void 返回类型 */public static void e(String tag, String msg) {if (isDeBug) {Log.w(tag, msg);}if (isWrite) {write(tag, msg);}}/** * 用于把日志内容写入制定的文件 * * @param @param tag 标识 * @param @param msg 要输出的内容 * @return void 返回类型 * @throws */public static void write(String tag, String msg) {String path = FileUtils.createMkdirsAndFiles(DIRPATH, LOGNAME);if (TextUtils.isEmpty(path)) {return;}String log = DateFormat.format(INFORMAT, System.currentTimeMillis())+ tag+ "========>>"+ msg+ "\n=================================分割线=================================";FileUtils.write2File(path, log, true);}/** * 用于把日志内容写入制定的文件 * * @param tag * 标签 * @param ex * 异常 */public static void write(Throwable ex) {write("", exToString(ex));}/** * 把异常信息转化为字符串 * * @param ex 异常信息 * @return 异常信息字符串 */private static String exToString(Throwable ex) {Writer writer = new StringWriter();PrintWriter printWriter = new PrintWriter(writer);ex.printStackTrace(printWriter);printWriter.close();String result = writer.toString();return result;}}
方案二:
方案一虽然在release情况无法输出了,但是对于发不出去的包,通过反编译还是可以看到log的,可以推出来我们的一些逻辑,这对于我们是不需要的
DEBUG通过一个final的boolean值控制,编译的时候,会自动去掉。
if (DEBUG) { Log.e(TAG, "err", e);}方案三:方案二虽然可以实现,但是还是比较复杂的。每次需要写三行,我们可以通过另一种方式实现这种策略(混淆配置)在混淆文件中:
-assumenosideeffects class android.util.Log { public static *** v(...); public static *** d(...); public static *** i(...); public static *** w(...); public static *** e(...);}
但是不可以配置:-dontoptimize
方案四:
这是一种系统开发常用的方法,我们的应用发布出去了,这时我们发现了问题,但是没有log怎么调试呢?这是就出现了方案四,我们可以动态配置在当前手机是否打开log
直接参照系统源码吧:
这里面有个知识点:
android.util.Log.isLoggable(TAG, level);这个开关时可以动态配置的,正常没有配置的时候,是返回false的。
当设置了
adb shell setprop log.tag.TAG VERBOSE
之后,就会返回true了/packages/services/Telephony/src/com/android/services/telephony/Log.java /* * Copyright 2014, The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.android.services.telephony;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.util.IllegalFormatException;import java.util.Locale;/** * Manages logging for the entire module. */final public class Log { // Generic tag for all In Call logging private static final String TAG = "Telephony"; public static final boolean FORCE_LOGGING = false; /* STOP SHIP if true */ public static final boolean DEBUG = isLoggable(android.util.Log.DEBUG); public static final boolean INFO = isLoggable(android.util.Log.INFO); public static final boolean VERBOSE = isLoggable(android.util.Log.VERBOSE); public static final boolean WARN = isLoggable(android.util.Log.WARN); public static final boolean ERROR = isLoggable(android.util.Log.ERROR); private Log() {} public static boolean isLoggable(int level) { return FORCE_LOGGING || android.util.Log.isLoggable(TAG, level); } public static void d(String prefix, String format, Object... args) { if (DEBUG) { android.util.Log.d(TAG, buildMessage(prefix, format, args)); } } public static void d(Object objectPrefix, String format, Object... args) { if (DEBUG) { android.util.Log.d(TAG, buildMessage(getPrefixFromObject(objectPrefix), format, args)); } } public static void i(String prefix, String format, Object... args) { if (INFO) { android.util.Log.i(TAG, buildMessage(prefix, format, args)); } } public static void i(Object objectPrefix, String format, Object... args) { if (INFO) { android.util.Log.i(TAG, buildMessage(getPrefixFromObject(objectPrefix), format, args)); } } public static void v(String prefix, String format, Object... args) { if (VERBOSE) { android.util.Log.v(TAG, buildMessage(prefix, format, args)); } } public static void v(Object objectPrefix, String format, Object... args) { if (VERBOSE) { android.util.Log.v(TAG, buildMessage(getPrefixFromObject(objectPrefix), format, args)); } } public static void w(String prefix, String format, Object... args) { if (WARN) { android.util.Log.w(TAG, buildMessage(prefix, format, args)); } } public static void w(Object objectPrefix, String format, Object... args) { if (WARN) { android.util.Log.w(TAG, buildMessage(getPrefixFromObject(objectPrefix), format, args)); } } public static void e(String prefix, Throwable tr, String format, Object... args) { if (ERROR) { android.util.Log.e(TAG, buildMessage(prefix, format, args), tr); } } public static void e(Object objectPrefix, Throwable tr, String format, Object... args) { if (ERROR) { android.util.Log.e(TAG, buildMessage(getPrefixFromObject(objectPrefix), format, args), tr); } } public static void wtf(String prefix, Throwable tr, String format, Object... args) { android.util.Log.wtf(TAG, buildMessage(prefix, format, args), tr); } public static void wtf(Object objectPrefix, Throwable tr, String format, Object... args) { android.util.Log.wtf(TAG, buildMessage(getPrefixFromObject(objectPrefix), format, args), tr); } public static void wtf(String prefix, String format, Object... args) { String msg = buildMessage(prefix, format, args); android.util.Log.wtf(TAG, msg, new IllegalStateException(msg)); } public static void wtf(Object objectPrefix, String format, Object... args) { String msg = buildMessage(getPrefixFromObject(objectPrefix), format, args); android.util.Log.wtf(TAG, msg, new IllegalStateException(msg)); } /** * Redact personally identifiable information for production users. * If we are running in verbose mode, return the original string, otherwise * return a SHA-1 hash of the input string. */ public static String pii(Object pii) { if (pii == null || VERBOSE) { return String.valueOf(pii); } return "[" + secureHash(String.valueOf(pii).getBytes()) + "]"; } private static String secureHash(byte[] input) { MessageDigest messageDigest; try { messageDigest = MessageDigest.getInstance("SHA-1"); } catch (NoSuchAlgorithmException e) { return null; } messageDigest.update(input); byte[] result = messageDigest.digest(); return encodeHex(result); } private static String encodeHex(byte[] bytes) { StringBuffer hex = new StringBuffer(bytes.length * 2); for (int i = 0; i < bytes.length; i++) { int byteIntValue = bytes[i] & 0xff; if (byteIntValue < 0x10) { hex.append("0"); } hex.append(Integer.toString(byteIntValue, 16)); } return hex.toString(); } private static String getPrefixFromObject(Object obj) { return obj == null ? "<null>" : obj.getClass().getSimpleName(); } private static String buildMessage(String prefix, String format, Object... args) { String msg; try { msg = (args == null || args.length == 0) ? format : String.format(Locale.US, format, args); } catch (IllegalFormatException ife) { wtf("Log", ife, "IllegalFormatException: formatString='%s' numArgs=%d", format, args.length); msg = format + " (An error occurred while formatting the message.)"; } return String.format(Locale.US, "%s: %s", prefix, msg); }}
以上的每个知识点都可以用于很多用途,不只是在log这里!
参考链接:
http://blog.csdn.net/ls703/article/details/42973553
http://blog.csdn.net/vk5176891/article/details/46537625
阅读全文
0 0
- Android Log的多场景使用
- Android Log的使用
- Android的log使用
- 多线程/多进程的使用场景-Android
- Log.IO的使用场景和改造思路
- android中log的使用
- 关于Android 的Log使用
- Android多进程使用场景
- Android 多进程使用场景
- Android多进程使用场景
- Android多进程使用场景
- if (log.isDebugEnabled()) {}使用场景初析
- if (log.isDebugEnabled()) {}使用场景初析
- 浅谈Android系统开发中LOG的使用--LOG(3)
- Android的Intent的使用场景
- android:PopupWindow的使用场景和注意事项
- android:PopupWindow的使用场景和注意事项
- Android开发Uri的使用场景
- 和为零的子矩阵-LintCode
- PHP基础知识篇(一)
- BZOJ1087 互不侵犯king(状压DP)
- (五)hadoop路径读取文件的通配符
- 150 多个 ML、NLP 和 Python 相关的教程
- Android Log的多场景使用
- 腾讯 TLC 大会半折票最后 1 天!!!
- 多条目加载
- 已知类,查找类所在jar包的pom引入
- 论文笔记 | 基于深度学习的乳腺转移瘤识别(Deep Learning for Identifying Metastatic Breast Cancer)
- 管理所有Filter
- python binascii 进制转换
- ubuntu 命令行分屏工具
- 一个简单的正则校验