今天看了一个google sample 发现demo中用的Log是自定义的,看了看发现写的挺简单的,用到了面向对象原则,给大家分享一下
- (依赖倒置原则 )将Log输出的函数提取到一个接口中,在具体的类中具体实现日志输入
public interface LogNode {
public void println(int priority, String tag, String msg, Throwable tr);
}
- 在需要输入Log的地方使用Log.xxx();方法;来输出信息
public class Log {
// Grabbing the native values from Android's native logging facilities,
// to make for easy migration and interop.
public static final int NONE = -1;
public static final int VERBOSE = android.util.Log.VERBOSE;
public static final int DEBUG = android.util.Log.DEBUG;
public static final int INFO = android.util.Log.INFO;
public static final int WARN = android.util.Log.WARN;
public static final int ERROR = android.util.Log.ERROR;
public static final int ASSERT = android.util.Log.ASSERT;
// 接口对象
private static LogNode mLogNode;
public static LogNode getLogNode() {
return mLogNode;
}
// 将具体的对象复制给mLogNode
public static void setLogNode(LogNode node) {
mLogNode = node;
}
// 根据不同的mLogNode执行不同的操作,一般Log.xx()之后再xx()中执行println(),再根据不同的mLogNode对象进行不同的操作
public static void println(int priority, String tag, String msg, Throwable tr) {
if (mLogNode != null) {
mLogNode.println(priority, tag, msg, tr);
}
}
public static void println(int priority, String tag, String msg) {
println(priority, tag, msg, null);
}
public static void v(String tag, String msg, Throwable tr) {
println(VERBOSE, tag, msg, tr);
}
public static void v(String tag, String msg) {
v(tag, msg, null);
}
public static void d(String tag, String msg, Throwable tr) {
println(DEBUG, tag, msg, tr);
}
public static void d(String tag, String msg) {
d(tag, msg, null);
}
public static void i(String tag, String msg, Throwable tr) {
println(INFO, tag, msg, tr);
}
public static void i(String tag, String msg) {
i(tag, msg, null);
}
public static void w(String tag, String msg, Throwable tr) {
println(WARN, tag, msg, tr);
}
public static void w(String tag, String msg) {
w(tag, msg, null);
}
public static void w(String tag, Throwable tr) {
w(tag, null, tr);
}
public static void e(String tag, String msg, Throwable tr) {
println(ERROR, tag, msg, tr);
}
public static void e(String tag, String msg) {
e(tag, msg, null);
}
public static void wtf(String tag, String msg, Throwable tr) {
println(ASSERT, tag, msg, tr);
}
public static void wtf(String tag, String msg) {
wtf(tag, msg, null);
}
public static void wtf(String tag, Throwable tr) {
wtf(tag, null, tr);
}
- 具体类实现LogNode接口执行println()方法
将LogWrapper对象赋值给Log类中的mLogNode,在执行Log.xx()时,最终执行的是LogWrapper函数中的println()函数,在println中将需要输出的数据进行处理后,再通过android.util.Log类中的println()函数将信息输出来.
在开发中,我们一般在程序中需要实时记录程序运行日志,这样我们可以在LogWrapper中的println中进行日志的记录操作,将日志保存在本地+上传到服务器.
public class LogWrapper implements LogNode {
@Override
public void println(int priority, String tag, String msg, Throwable tr) {
// There actually are log methods that don't take a msg parameter. For now,
// if that's the case, just convert null to the empty string and move on.
String useMsg = msg;
if (useMsg == null) {
useMsg = "";
}
// If an exeption was provided, convert that exception to a usable string and attach
// it to the end of the msg method.
if (tr != null) {
msg += "\n" + Log.getStackTraceString(tr);
}
// This is functionally identical to Log.x(tag, useMsg);
// For instance, if priority were Log.VERBOSE, this would be the same as Log.v(tag, useMsg)
Log.println(priority, tag, useMsg);
// If this isn't the last node in the chain, move things along.
if (mNext != null) {
mNext.println(priority, tag, msg, tr);
}
}
}