概述
build(app)的配置
//初次新建记得添加
// {"kind":"error","text":"Invoke-customs are only supported starting with Android O
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
buildTypes {
def date = new Date().format("yyyy-MM-dd-hh-mm-ss")
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
buildConfigField("String", "apkBuildTime", ""${date}"")
buildConfigField "boolean", "IS_DEBUG", "false"
}
debug {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
//设置BuildConfig 生成IS_DEBUG、apkBuildTime等变量
buildConfigField("String", "apkBuildTime", ""${date}"")
buildConfigField "boolean", "IS_DEBUG", "true"
}
}
// timber
implementation 'com.jakewharton.timber:timber:4.1.1'
LocalApplication进行初始化
import android.app.Application;
import android.util.Log;
import example.com.summary.util.Logger;
public class LocalApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
_initConfig();
}
private void _initConfig() {
if (BuildConfig.IS_DEBUG) {
Logger.builder()
.setLogPriority(Log.DEBUG)
.isShowThreadInfo(true)
.initialize(true);
} else {
Logger.builder()
.setLogPriority(Log.ASSERT)
.isShowThreadInfo(true)
.initialize(false);
}
Logger.d(Logger._TJ, "on Appliction Create set Logger Iml");
}
}
import android.support.annotation.CheckResult;
import android.support.annotation.IntDef;
import android.support.annotation.LongDef;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.StringReader;
import java.io.StringWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Field;
import java.util.Collection;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import timber.log.Timber;
public class Logger {
/************************************* - TAG - ****************************************/
//TAG最大标记为63,最多左移63为,因为long是8字节 64位
public static final long BASE_ONE = 1L; //
/** 1~15属于公共资源 */
public static final long _PUBLIC = Short.MAX_VALUE; //打印公共资源的全部log
public static final long _NET = BASE_ONE << 1; //网络请求
public static final long _READ_ASSETS = BASE_ONE << 2; //网络请求
public static final long _FOCUSE = BASE_ONE << 15; // 焦点变化
/** 建晶 16~31*/
public static final long _TJ = _PUBLIC << 16;
public static final long _TJ_ListPresenter = BASE_ONE << 16; //
public static final long _TJ_ChannelPresenter = BASE_ONE << 17; //
/** 佳南 32~47*/
public static final long _JN = _TJ << 16;
public static final long _TM_SplashActivity = BASE_ONE << 32;
/** 记得把新建的TAG注入到下面的对应栏目中 TAG的取值只能取如下几种*/
@Retention(RetentionPolicy.SOURCE)
@LongDef({
/**公共资源*/_PUBLIC,_NET,_READ_ASSETS,
_TJ, _TJ_ListPresenter,_TJ_ChannelPresenter,
_JN,_TM_SplashActivity
})
@interface LogType {}
private static final long MY_LOG = _FOCUSE|_TJ|_JN;
/* MY_LOG 取值事例:
private static final long MY_LOG = _TJ;
private static final long MY_LOG = _TJ | _NET;
private static final long MY_LOG = _TJ_ListPresenter | _TM_SplashActivity;
*/
/************************************* - LOG - ****************************************/
/**
* LogLevel的取值只能取如下几种
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef({Log.VERBOSE, Log.DEBUG, Log.INFO, Log.WARN, Log.ERROR, Log.ASSERT})
@interface LogLevel {}
protected Logger() {}
public static Timber.Tree t(String tag) {
return Timber.tag(tag);
}
/**eg:Logger.v(Logger._NET,"name = %s", name);*/
public static void v(@LogType long log, String message, Object... args) {
if ((log & MY_LOG) != 0 ){
Timber.v(handleNullMsg(message), args);
}
}
/**eg:Logger.v(Logger._NET,"name = %s", name);*/
public static void d(@LogType long log, String message, Object... args) {
if ((log & MY_LOG) != 0 ) {
Timber.d(handleNullMsg(message), args);
}
}
/**eg:Logger.i(Logger._NET,"name = %s", name);*/
public static void i(@LogType long log, String message, Object... args) {
if ((log & MY_LOG) != 0 ){
Timber.i(handleNullMsg(message), args);
}
}
/**eg:Logger.i("name = %s", name); 所有人可见*/
public static void i(String message, Object... args) {
Timber.i(handleNullMsg(message), args);
}
/**eg:Logger.w("name = %s", name); 所有人可见*/
public static void w(String message, Object... args) {
Timber.w(handleNullMsg(message), args);
}
/**eg:Logger.w(throwable,"name = %s", name); 所有人可见*/
public static void w(Throwable throwable, String message, Object... args) {
Timber.w(throwable, handleNullMsg(message), args);
}
/**eg:Logger.e("name = %s", name); 所有人可见*/
public static void e(String message, Object... args) {
Timber.e(handleNullMsg(message), args);
}
/**eg:Logger.e(throwable); 所有人可见*/
public static void e(Throwable throwable) {
Timber.e(throwable, "");
}
/**eg:Logger.e(throwable,"name = %s", name); 所有人可见*/
public static void e(Throwable throwable, String message, Object... args) {
Timber.e(throwable, handleNullMsg(message), args);
}
/**eg:Logger.wft(Logger._NET,"name = %s", name);*/
public static void wtf(@LogType long log, String message, Object... args) {
if ((log & MY_LOG) != 0 ) {
Timber.wtf(handleNullMsg(message), args);
}
}
/**eg:Logger.wft(Logger._NET,throwable,"name = %s", name);*/
public static void wtf(@LogType long log, Throwable throwable, String message, Object... args) {
if ((log & MY_LOG) != 0 ) {
Timber.wtf(throwable, handleNullMsg(message), args);
}
}
/**eg:Logger.json(Logger._NET,json);*/
public static void json(@LogType long log, String json) {
if ((log & MY_LOG) != 0 ) {
Timber.d(XmlJsonParser.json(json));
}
}
/**eg:Logger.xml(Logger._NET,xml);*/
public static void xml(@LogType long log, String xml) {
if ((log & MY_LOG) != 0 ) {
Timber.d(XmlJsonParser.xml(xml));
}
}
public static void object(@LogType long log, Object object) {
if ((log & MY_LOG) != 0 ) {
Timber.d(ObjParser.parseObj(object));
}
}
/**
* Timber will swallow message if it's null and there's no throwable.
*/
@NonNull
private static String handleNullMsg(String message) {
if (message == null) {
message = "null";
}
return message;
}
public static Builder builder() {
return new Builder();
}
/************************************* - Builder - ****************************************/
/**
* 通过Builder初始化Timber
* Builder is a wrapper of {@link Timber}
* @author
*/
public static final class Builder {
int methodOffset = 0;
boolean showMethodLink = true;
boolean showThreadInfo = false;
int priority = Log.DEBUG;
public Builder setMethodOffset(int methodOffset) {
this.methodOffset = methodOffset;
return this;
}
public Builder isShowThreadInfo(boolean showThreadInfo) {
this.showThreadInfo = showThreadInfo;
return this;
}
public Builder isShowMethodLink(boolean showMethodLink) {
this.showMethodLink = showMethodLink;
return this;
}
/**
* @param priority one of
* {@link Log#DEBUG}
*/
public Builder setLogPriority(@LogLevel int priority) {
this.priority = priority;
return this;
}
public void initialize(boolean isMustLog) {
if (isMustLog) priority = Log.VERBOSE;
Timber.plant(new MyDebugTree(this));
}
}
/************************************* - DebugTree - ****************************************/
private static final class MyDebugTree extends Timber.DebugTree{
private int methodOffset = 0;
private boolean showMethodLink = true;
private boolean showThreadInfo = false;
private int priority = Log.DEBUG;
private static final int STACK_OFFSET = 8;
private static final String BOTTOM_BORDER = "╚═══════════════════════════";
private static final String PREFIX_BORDER = "║";
/**
* 因为如果设置了tag,那么会在timber中多走一个方法,方法栈会发生变化,造成不准确的情况。
*/
private boolean isCustomTag = true;
private StringBuilder sb = new StringBuilder();
private final String PROPERTY = System.getProperty("line.separator");
public MyDebugTree(Builder builder) {
methodOffset = builder.methodOffset;
showMethodLink = builder.showMethodLink;
showThreadInfo = builder.showThreadInfo;
priority = builder.priority;
}
/**
* rule for auto tag
*/
@Override
protected String createStackElementTag(StackTraceElement ignored) {
isCustomTag = false;
int offset = STACK_OFFSET + methodOffset - 1;
return super.createStackElementTag(new Throwable().getStackTrace()[offset]);
}
protected void log(int priority, String tag, @NonNull String message, Throwable ignored) {
String[] lines = message.split(PROPERTY);
StringBuilder buf = new StringBuilder();
for (int i = 0; i < lines.length; i++) {
buf.append(PREFIX_BORDER + lines[i] + "n");
}
String relLog = String.format("%sn%s%s", getTail(), buf.toString(), BOTTOM_BORDER);
super.log((priority), tag, relLog, null);
isCustomTag = true;
//
for (int i = 0, length = lines.length; i < length; i++) {
//
if (i == length - 1) {
//
// last line
//
super.log(priority, tag, PREFIX_BORDER + lines[i] + getTail(), null);
//
} else {
//
super.log((priority), tag, PREFIX_BORDER + lines[i], null);
//
}
//
}
//
// Finally print bottom line
//
super.log((priority), tag, BOTTOM_BORDER, null);
//
isCustomTag = true;
}
/**
* ==> onCreate(MainActivity.java:827) Thread:main
*/
private String getTail() {
if (!showMethodLink) {
return "";
}
int index = STACK_OFFSET + methodOffset + 1;
if (isCustomTag) {
index -= 2;
}
final StackTraceElement stack = Thread.currentThread().getStackTrace()[index];
if (sb.length() < 0) {
sb = new StringBuilder();
} else {
sb.setLength(0);
}
sb.append(String.format(" ==>
Method:
%s(%s:%s)",
stack.getMethodName(),
stack.getFileName(),
stack.getLineNumber()));
if (showThreadInfo) {
sb.append(" Thread: ").append(Thread.currentThread().getName()); // Thread:main
}
return sb.toString();
}
/**
* 根据级别显示log
*/
@Override
protected boolean isLoggable(int priority) {
return priority >= this.priority;
}
}
/*----------------------------------- END --------------------------------------------------*/
/*以下是工具类-不对外提供*/
/************************************* - XmlJsonParser - ****************************************/
private static final class XmlJsonParser {
/**
* It is used for json pretty print
*/
private static final int JSON_INDENT = 4;
@CheckResult
public static String xml(String xml) {
if (TextUtils.isEmpty(xml)) {
return "Empty/Null xml content.(This msg from logger)";
}
try {
Source xmlInput = new StreamSource(new StringReader(xml));
StreamResult xmlOutput = new StreamResult(new StringWriter());
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
transformer.transform(xmlInput, xmlOutput);
return xmlOutput.getWriter().toString().replaceFirst(">", ">n");
} catch (TransformerException e) {
return e.getCause().getMessage() + "n" + xml;
}
}
@CheckResult
public static String json(@Nullable String json) {
if (TextUtils.isEmpty(json)) {
return "Empty/Null json content.(This msg from logger)";
}
try {
if (json.startsWith("{")) {
return new JSONObject(json).toString(JSON_INDENT);
} else if (json.startsWith("[")) {
return new JSONArray(json).toString(JSON_INDENT);
}
} catch (JSONException e) {
return e.getCause().getMessage() + "n" + json;
}
return "Log error!.(This msg from logger)";
}
}
/************************************* - ObjParser - ****************************************/
private static final class ObjParser {
// 基本数据类型
private final static String[] TYPES = {"int", "java.lang.String", "boolean", "char",
"float", "double", "long", "short", "byte"};
public static String parseObj(Object object) {
if (object == null) {
return "null";
}
final String simpleName = object.getClass().getSimpleName();
if (object.getClass().isArray()) {
StringBuilder msg = new StringBuilder("Temporarily not support more than two dimensional Array!");
int dim = ArrayParser.getArrayDimension(object);
switch (dim) {
case 1:
Pair pair = ArrayParser.arrayToString(object);
msg = new StringBuilder(simpleName.replace("[]", "[" + pair.first + "] {n"));
msg.append(pair.second).append("n");
break;
case 2:
Pair pair1 = ArrayParser.arrayToObject(object);
Pair pair2 = (Pair) pair1.first;
msg = new StringBuilder(simpleName.replace("[][]", "[" + pair2.first + "][" + pair2.second + "] {n"));
msg.append(pair1.second).append("n");
break;
default:
break;
}
return msg + "}";
} else if (object instanceof Collection) {
Collection collection = (Collection) object;
String msg = "%s size = %d [n";
msg = String.format(Locale.ENGLISH, msg, simpleName, collection.size());
if (!collection.isEmpty()) {
Iterator iterator = collection.iterator();
int flag = 0;
while (iterator.hasNext()) {
String itemString = "[%d]:%s%s";
Object item = iterator.next();
msg += String.format(Locale.ENGLISH, itemString,
flag,
objectToString(item),
flag++ < collection.size() - 1 ? ",n" : "n");
}
}
return msg + "n]";
} else if (object instanceof Map) {
String msg = simpleName + " {n";
Map map = (Map) object;
Set keys = map.keySet();
for (Object key : keys) {
String itemString = "[%s -> %s]n";
Object value = map.get(key);
msg += String.format(itemString, objectToString(key), objectToString(value));
}
return msg + "}";
} else {
return objectToString(object);
}
}
/**
* 将对象转化为String
*/
protected static <T> String objectToString(T object) {
if (object == null) {
return "Object{object is null}";
}
if (object.toString().startsWith(object.getClass().getName() + "@")) {
StringBuilder builder = new StringBuilder(object.getClass().getSimpleName() + "{");
Field[] fields = object.getClass().getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
boolean flag = false;
for (String type : TYPES) {
if (field.getType().getName().equalsIgnoreCase(type)) {
flag = true;
Object value = null;
try {
value = field.get(object);
} catch (IllegalAccessException e) {
value = e;
} finally {
builder.append(String.format("%s=%s, ", field.getName(),
value == null ? "null" : value.toString()));
}
}
}
if (!flag) {
builder.append(String.format("%s=%s, ", field.getName(), "Object"));
}
}
return builder.replace(builder.length() - 2, builder.length() - 1, "}").toString();
} else {
return object.toString();
}
}
}
/************************************* - ArrayParser - ****************************************/
private static final class ArrayParser {
/**
* 获取数组的纬度
*/
public static int getArrayDimension(Object objects) {
int dim = 0;
for (int i = 0; i < objects.toString().length(); ++i) {
if (objects.toString().charAt(i) == '[') {
++dim;
} else {
break;
}
}
return dim;
}
public static Pair<Pair<Integer, Integer>, String> arrayToObject(Object object) {
StringBuilder builder = new StringBuilder();
int cross, vertical;
if (object instanceof int[][]) {
int[][] ints = (int[][]) object;
cross = ints.length;
vertical = cross == 0 ? 0 : ints[0].length;
for (int[] ints1 : ints) {
builder.append(arrayToString(ints1).second).append("n");
}
} else if (object instanceof byte[][]) {
byte[][] ints = (byte[][]) object;
cross = ints.length;
vertical = cross == 0 ? 0 : ints[0].length;
for (byte[] ints1 : ints) {
builder.append(arrayToString(ints1).second).append("n");
}
} else if (object instanceof short[][]) {
short[][] ints = (short[][]) object;
cross = ints.length;
vertical = cross == 0 ? 0 : ints[0].length;
for (short[] ints1 : ints) {
builder.append(arrayToString(ints1).second).append("n");
}
} else if (object instanceof long[][]) {
long[][] ints = (long[][]) object;
cross = ints.length;
vertical = cross == 0 ? 0 : ints[0].length;
for (long[] ints1 : ints) {
builder.append(arrayToString(ints1).second).append("n");
}
} else if (object instanceof float[][]) {
float[][] ints = (float[][]) object;
cross = ints.length;
vertical = cross == 0 ? 0 : ints[0].length;
for (float[] ints1 : ints) {
builder.append(arrayToString(ints1).second).append("n");
}
} else if (object instanceof double[][]) {
double[][] ints = (double[][]) object;
cross = ints.length;
vertical = cross == 0 ? 0 : ints[0].length;
for (double[] ints1 : ints) {
builder.append(arrayToString(ints1).second).append("n");
}
} else if (object instanceof boolean[][]) {
boolean[][] ints = (boolean[][]) object;
cross = ints.length;
vertical = cross == 0 ? 0 : ints[0].length;
for (boolean[] ints1 : ints) {
builder.append(arrayToString(ints1).second).append("n");
}
} else if (object instanceof char[][]) {
char[][] ints = (char[][]) object;
cross = ints.length;
vertical = cross == 0 ? 0 : ints[0].length;
for (char[] ints1 : ints) {
builder.append(arrayToString(ints1).second).append("n");
}
} else {
Object[][] objects = (Object[][]) object;
cross = objects.length;
vertical = cross == 0 ? 0 : objects[0].length;
for (Object[] objects1 : objects) {
builder.append(arrayToString(objects1).second).append("n");
}
}
return Pair.create(Pair.create(cross, vertical), builder.toString());
}
/**
* 数组转化为字符串
*/
public static Pair arrayToString(Object object) {
StringBuilder builder = new StringBuilder("[");
int length;
if (object instanceof int[]) {
int[] ints = (int[]) object;
length = ints.length;
for (int i : ints) {
builder.append(i).append(",t");
}
} else if (object instanceof byte[]) {
byte[] bytes = (byte[]) object;
length = bytes.length;
for (byte item : bytes) {
builder.append(item).append(",t");
}
} else if (object instanceof short[]) {
short[] shorts = (short[]) object;
length = shorts.length;
for (short item : shorts) {
builder.append(item).append(",t");
}
} else if (object instanceof long[]) {
long[] longs = (long[]) object;
length = longs.length;
for (long item : longs) {
builder.append(item).append(",t");
}
} else if (object instanceof float[]) {
float[] floats = (float[]) object;
length = floats.length;
for (float item : floats) {
builder.append(item).append(",t");
}
} else if (object instanceof double[]) {
double[] doubles = (double[]) object;
length = doubles.length;
for (double item : doubles) {
builder.append(item).append(",t");
}
} else if (object instanceof boolean[]) {
boolean[] booleans = (boolean[]) object;
length = booleans.length;
for (boolean item : booleans) {
builder.append(item).append(",t");
}
} else if (object instanceof char[]) {
char[] chars = (char[]) object;
length = chars.length;
for (char item : chars) {
builder.append(item).append(",t");
}
} else {
Object[] objects = (Object[]) object;
length = objects.length;
for (Object item : objects) {
builder.append(ObjParser.objectToString(item)).append(",t");
}
}
return Pair.create(length, builder.replace(builder.length() - 2, builder.length(), "]").toString());
}
}
}
最后
以上就是深情大树为你收集整理的Android Logger便捷使用的全部内容,希望文章能够帮你解决Android Logger便捷使用所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复