修改交友布局
This commit is contained in:
@@ -0,0 +1,206 @@
|
||||
package com.xscm.moduleutil.utils.logger;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* SCore
|
||||
* Created by ShangChuanliang
|
||||
* on 2017/10/12.
|
||||
*/
|
||||
public final class DataLogger implements DataLoggingInterceptor.Logger {
|
||||
private final StringBuilder mMessage = new StringBuilder();
|
||||
|
||||
public static class LogAdapter extends com.orhanobut.logger.AndroidLogAdapter {
|
||||
private final boolean mDebuggable;
|
||||
|
||||
public LogAdapter(boolean debuggable) {
|
||||
super();
|
||||
mDebuggable = debuggable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLoggable(int priority, @Nullable String tag) {
|
||||
// return super.isLoggable(priority, tag);
|
||||
return mDebuggable;
|
||||
}
|
||||
}
|
||||
|
||||
public static class LogUtil {
|
||||
public static void init(boolean debuggable) {
|
||||
com.orhanobut.logger.Logger.addLogAdapter(new LogAdapter(debuggable));
|
||||
}
|
||||
|
||||
public static void d(String message) {
|
||||
com.orhanobut.logger.Logger.d(message);
|
||||
}
|
||||
|
||||
public static void i(String message) {
|
||||
com.orhanobut.logger.Logger.i(message);
|
||||
}
|
||||
|
||||
public static void w(String message, Throwable e) {
|
||||
String info = e != null ? e.toString() : "null";
|
||||
com.orhanobut.logger.Logger.w(message + ":" + info);
|
||||
}
|
||||
|
||||
public static void e(String message, Throwable e) {
|
||||
com.orhanobut.logger.Logger.e(e, message);
|
||||
}
|
||||
|
||||
public static void json(String json) {
|
||||
com.orhanobut.logger.Logger.json(json);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(String message) {
|
||||
// 请求或者响应开始
|
||||
if (message.startsWith(DataLoggingInterceptor.sLogStartFlag)) {
|
||||
mMessage.setLength(0);
|
||||
return;
|
||||
}
|
||||
// 响应结束,打印整条日志
|
||||
if (message.startsWith(DataLoggingInterceptor.sLogEndFlag)) {
|
||||
LogUtil.d(mMessage.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
// 以{}或者[]形式的说明是响应结果的json数据,需要进行格式化
|
||||
if ((message.startsWith("{") && message.endsWith("}"))
|
||||
|| (message.startsWith("[") && message.endsWith("]"))) {
|
||||
message = formatJson(decodeUnicode(message));
|
||||
}
|
||||
// 追加消息
|
||||
try { mMessage.append(message.concat("\n"));
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
mMessage.setLength(0);
|
||||
}
|
||||
|
||||
private static String formatJson(String jsonStr) {
|
||||
if (null == jsonStr || "".equals(jsonStr)) return "";
|
||||
StringBuilder sb = new StringBuilder();
|
||||
char last = '\0';
|
||||
char current = '\0';
|
||||
int indent = 0;
|
||||
for (int i = 0; i < jsonStr.length(); i++) {
|
||||
last = current;
|
||||
current = jsonStr.charAt(i);
|
||||
//遇到{ [换行,且下一行缩进
|
||||
switch (current) {
|
||||
case '{':
|
||||
case '[':
|
||||
sb.append(current);
|
||||
sb.append('\n');
|
||||
indent++;
|
||||
addIndentBlank(sb, indent);
|
||||
break;
|
||||
//遇到} ]换行,当前行缩进
|
||||
case '}':
|
||||
case ']':
|
||||
sb.append('\n');
|
||||
indent--;
|
||||
addIndentBlank(sb, indent);
|
||||
sb.append(current);
|
||||
break;
|
||||
//遇到,换行
|
||||
case ',':
|
||||
sb.append(current);
|
||||
if (last != '\\') {
|
||||
sb.append('\n');
|
||||
addIndentBlank(sb, indent);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
sb.append(current);
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加space
|
||||
*
|
||||
* @param sb
|
||||
* @param indent
|
||||
*/
|
||||
private static void addIndentBlank(StringBuilder sb, int indent) {
|
||||
for (int i = 0; i < indent; i++) {
|
||||
sb.append('\t');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* http 请求数据返回 json 中中文字符为 unicode 编码转汉字转码
|
||||
*
|
||||
* @param theString
|
||||
* @return 转化后的结果.
|
||||
*/
|
||||
private static String decodeUnicode(String theString) {
|
||||
char aChar;
|
||||
int len = theString.length();
|
||||
StringBuilder outBuffer = new StringBuilder(len);
|
||||
for (int x = 0; x < len; ) {
|
||||
aChar = theString.charAt(x++);
|
||||
if (aChar == '\\') {
|
||||
aChar = theString.charAt(x++);
|
||||
if (aChar == 'u') {
|
||||
int value = 0;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
aChar = theString.charAt(x++);
|
||||
switch (aChar) {
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
value = (value << 4) + aChar - '0';
|
||||
break;
|
||||
case 'a':
|
||||
case 'b':
|
||||
case 'c':
|
||||
case 'd':
|
||||
case 'e':
|
||||
case 'f':
|
||||
value = (value << 4) + 10 + aChar - 'a';
|
||||
break;
|
||||
case 'A':
|
||||
case 'B':
|
||||
case 'C':
|
||||
case 'D':
|
||||
case 'E':
|
||||
case 'F':
|
||||
value = (value << 4) + 10 + aChar - 'A';
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException(
|
||||
"Malformed \\uxxxx encoding.");
|
||||
}
|
||||
|
||||
}
|
||||
outBuffer.append((char) value);
|
||||
} else {
|
||||
if (aChar == 't')
|
||||
aChar = '\t';
|
||||
else if (aChar == 'r')
|
||||
aChar = '\r';
|
||||
else if (aChar == 'n')
|
||||
aChar = '\n';
|
||||
else if (aChar == 'f')
|
||||
aChar = '\f';
|
||||
outBuffer.append(aChar);
|
||||
}
|
||||
} else
|
||||
outBuffer.append(aChar);
|
||||
}
|
||||
return outBuffer.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,215 @@
|
||||
package com.xscm.moduleutil.utils.logger;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.net.URLDecoder;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import okhttp3.Connection;
|
||||
import okhttp3.Headers;
|
||||
import okhttp3.Interceptor;
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.Protocol;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.Response;
|
||||
import okhttp3.ResponseBody;
|
||||
import okhttp3.internal.http.HttpHeaders;
|
||||
import okio.Buffer;
|
||||
import okio.BufferedSource;
|
||||
|
||||
/**
|
||||
* SCore
|
||||
* Created by ShangChuanliang
|
||||
* on 2017/12/21.
|
||||
*/
|
||||
public class DataLoggingInterceptor implements Interceptor {
|
||||
private static final String sFormatLine =
|
||||
"===========================================================================================";
|
||||
public static final String sLogStartFlag = "==scliang==log==start==";
|
||||
public static final String sLogEndFlag = "==scliang==log==end==";
|
||||
private static final Charset UTF8 = StandardCharsets.UTF_8;
|
||||
|
||||
public interface Logger {
|
||||
void reset();
|
||||
void log(String message);
|
||||
}
|
||||
|
||||
public DataLoggingInterceptor(Logger logger) {
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
private final Logger logger;
|
||||
|
||||
@NotNull
|
||||
@Override public Response intercept(@NonNull Chain chain) throws IOException {
|
||||
Request request = chain.request();
|
||||
|
||||
logger.reset();
|
||||
logger.log(sLogStartFlag);
|
||||
logger.log(sFormatLine);
|
||||
|
||||
RequestBody requestBody = request.body();
|
||||
boolean hasRequestBody = requestBody != null;
|
||||
|
||||
Connection connection = chain.connection();
|
||||
Protocol protocol = connection != null ? connection.protocol() : Protocol.HTTP_1_1;
|
||||
String requestStartMessage = request.method() + " " + request.url() + " " + protocol;
|
||||
logger.log(requestStartMessage);
|
||||
|
||||
if (hasRequestBody) {
|
||||
// Request body headers are only present when installed as a network interceptor. Force
|
||||
// them to be included (when available) so there values are known.
|
||||
if (requestBody.contentType() != null) {
|
||||
logger.log("Content-Type: " + requestBody.contentType());
|
||||
}
|
||||
if (requestBody.contentLength() != -1) {
|
||||
logger.log("Content-Length: " + requestBody.contentLength());
|
||||
}
|
||||
}
|
||||
|
||||
Headers rHeaders = request.headers();
|
||||
for (int i = 0, count = rHeaders.size(); i < count; i++) {
|
||||
String name = rHeaders.name(i);
|
||||
// Skip headers from the request body as they are explicitly logged above.
|
||||
if (!"Content-Type".equalsIgnoreCase(name) && !"Content-Length".equalsIgnoreCase(name)) {
|
||||
logger.log(name + ": " + rHeaders.value(i));
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasRequestBody) {
|
||||
logger.log("END " + request.method());
|
||||
} else if (bodyEncoded(request.headers())) {
|
||||
logger.log("END " + request.method() + " (encoded body omitted)");
|
||||
} else {
|
||||
Buffer buffer = new Buffer();
|
||||
requestBody.writeTo(buffer);
|
||||
|
||||
Charset charset = UTF8;
|
||||
MediaType contentType = requestBody.contentType();
|
||||
if (contentType != null) {
|
||||
charset = contentType.charset(UTF8);
|
||||
}
|
||||
|
||||
if (charset != null) {
|
||||
logger.log(sFormatLine);
|
||||
if (isPlaintext(buffer)) {
|
||||
try {
|
||||
String requestStr = URLDecoder.decode(buffer.readString(charset), "UTF-8");
|
||||
String[] strs = requestStr.split("&");
|
||||
for (String str : strs) {
|
||||
logger.log(str);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.log(buffer.readString(charset));
|
||||
}
|
||||
logger.log("END " + request.method()
|
||||
+ " (" + requestBody.contentLength() + "-byte body)");
|
||||
} else {
|
||||
logger.log("END " + request.method() + " (binary "
|
||||
+ requestBody.contentLength() + "-byte body omitted)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logger.log(sFormatLine);
|
||||
|
||||
long startNs = System.nanoTime();
|
||||
Response response;
|
||||
try {
|
||||
response = chain.proceed(request);
|
||||
} catch (Exception e) {
|
||||
logger.log("HTTP FAILED: " + e);
|
||||
logger.log(sLogEndFlag);
|
||||
throw e;
|
||||
}
|
||||
|
||||
long tookMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs);
|
||||
ResponseBody responseBody = response.body();
|
||||
if (responseBody != null) {
|
||||
long contentLength = responseBody.contentLength();
|
||||
String bodySize = contentLength != -1 ? contentLength + "-byte" : "unknown-length";
|
||||
logger.log(response.code() + " " + response.message() + " "
|
||||
+ response.request().url() + " (" + tookMs + "ms)");
|
||||
|
||||
Headers headers = response.headers();
|
||||
for (int i = 0, count = headers.size(); i < count; i++) {
|
||||
logger.log(headers.name(i) + ": " + headers.value(i));
|
||||
}
|
||||
|
||||
if (!HttpHeaders.hasBody(response)) {
|
||||
logger.log("END HTTP");
|
||||
} else if (bodyEncoded(response.headers())) {
|
||||
logger.log("END HTTP (encoded body omitted)");
|
||||
} else {
|
||||
BufferedSource source = responseBody.source();
|
||||
if (source.isOpen()) {
|
||||
source.request(Long.MAX_VALUE); // Buffer the entire body.
|
||||
Buffer buffer = source.buffer();
|
||||
|
||||
Charset charset = UTF8;
|
||||
MediaType contentType = responseBody.contentType();
|
||||
if (contentType != null) {
|
||||
charset = contentType.charset(UTF8);
|
||||
}
|
||||
|
||||
if (!isPlaintext(buffer)) {
|
||||
logger.log("END HTTP (binary " + buffer.size() + "-byte body omitted)");
|
||||
logger.log(sFormatLine);
|
||||
logger.log(sLogEndFlag);
|
||||
return response;
|
||||
}
|
||||
|
||||
if (contentLength != 0 && charset != null) {
|
||||
logger.log(sFormatLine);
|
||||
logger.log(buffer.clone().readString(charset));
|
||||
}
|
||||
|
||||
logger.log("END HTTP (" + buffer.size() + "-byte body)");
|
||||
} else {
|
||||
logger.log("END HTTP");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logger.log(sFormatLine);
|
||||
logger.log(sLogEndFlag);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the body in question probably contains human readable text. Uses a small sample
|
||||
* of code points to detect unicode control characters commonly used in binary file signatures.
|
||||
*/
|
||||
private static boolean isPlaintext(Buffer buffer) {
|
||||
try {
|
||||
Buffer prefix = new Buffer();
|
||||
long byteCount = buffer.size() < 64 ? buffer.size() : 64;
|
||||
buffer.copyTo(prefix, 0, byteCount);
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if (prefix.exhausted()) {
|
||||
break;
|
||||
}
|
||||
int codePoint = prefix.readUtf8CodePoint();
|
||||
if (Character.isISOControl(codePoint) && !Character.isWhitespace(codePoint)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} catch (EOFException e) {
|
||||
return false; // Truncated UTF-8 sequence.
|
||||
}
|
||||
}
|
||||
|
||||
private boolean bodyEncoded(Headers headers) {
|
||||
String contentEncoding = headers.get("Content-Encoding");
|
||||
return contentEncoding != null && !contentEncoding.equalsIgnoreCase("identity");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
package com.xscm.moduleutil.utils.logger;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.lang.ref.SoftReference;
|
||||
|
||||
/**
|
||||
* SCore
|
||||
* Created by ShangChuanliang
|
||||
* on 2017/9/29.
|
||||
*/
|
||||
public class Logger {
|
||||
public interface OnLoggerListener {
|
||||
void onLogI(String buildType, String tag, String msg);
|
||||
void onLogD(String buildType, String tag, String msg);
|
||||
void onLogE(String buildType, String tag, String msg);
|
||||
void onLogV(String buildType, String tag, String msg);
|
||||
void onLogW(String buildType, String tag, String msg);
|
||||
}
|
||||
|
||||
private Logger() {}
|
||||
private static SoftReference<OnLoggerListener> sOnLoggerListener;
|
||||
|
||||
private static final String Tag = "SLog";
|
||||
|
||||
private static String BuildType;
|
||||
private static boolean IsRelease;
|
||||
private static boolean IsBeta;
|
||||
private static boolean Loggable;
|
||||
|
||||
public static void init(String buildType) {
|
||||
BuildType = buildType;
|
||||
IsRelease = "release".equalsIgnoreCase(BuildType);
|
||||
IsBeta = "beta".equalsIgnoreCase(BuildType);
|
||||
Loggable = !IsRelease;
|
||||
}
|
||||
|
||||
public static void setOnLoggerListener(OnLoggerListener listener) {
|
||||
sOnLoggerListener = new SoftReference<>(listener);
|
||||
}
|
||||
|
||||
public static String getBuildType() {
|
||||
return BuildType;
|
||||
}
|
||||
|
||||
public static boolean isRelease() {
|
||||
return IsRelease;
|
||||
}
|
||||
|
||||
public static boolean isBeta() {
|
||||
return IsBeta;
|
||||
}
|
||||
|
||||
public static boolean isLoggable() {
|
||||
return Loggable;
|
||||
}
|
||||
|
||||
public static void i(String msg, Object... args) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Object arg : args) if (arg != null) sb.append(";").append(arg);
|
||||
callOnLoggerListener(1, BuildType, Tag, msg + sb.toString());
|
||||
if (isLoggable()) Log.i(Tag, msg + sb.toString());
|
||||
}
|
||||
|
||||
public static void d(String msg, Object... args) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Object arg : args) if (arg != null) sb.append(";").append(arg);
|
||||
callOnLoggerListener(2, BuildType, Tag, msg + sb.toString());
|
||||
if (isLoggable()) Log.d(Tag, msg + sb.toString());
|
||||
}
|
||||
|
||||
public static void e(String msg, Object... args) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Object arg : args) if (arg != null) sb.append(";").append(arg);
|
||||
callOnLoggerListener(3, BuildType, Tag, msg + sb.toString());
|
||||
if (isLoggable()) Log.e(Tag, msg + sb.toString());
|
||||
}
|
||||
|
||||
public static void v(String msg, Object... args) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Object arg : args) if (arg != null) sb.append(";").append(arg);
|
||||
callOnLoggerListener(4, BuildType, Tag, msg + sb.toString());
|
||||
if (isLoggable()) Log.v(Tag, msg + sb.toString());
|
||||
}
|
||||
|
||||
public static void w(String msg, Object... args) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Object arg : args) if (arg != null) sb.append(";").append(arg);
|
||||
callOnLoggerListener(5, BuildType, Tag, msg + sb.toString());
|
||||
if (isLoggable()) Log.w(Tag, msg + sb.toString());
|
||||
}
|
||||
|
||||
private static void callOnLoggerListener(int type, String buildType, String tag, String msg) {
|
||||
if (sOnLoggerListener == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
OnLoggerListener listener = sOnLoggerListener.get();
|
||||
|
||||
if (listener == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case 1: listener.onLogI(buildType, tag, msg); break;
|
||||
case 2: listener.onLogD(buildType, tag, msg); break;
|
||||
case 3: listener.onLogE(buildType, tag, msg); break;
|
||||
case 4: listener.onLogV(buildType, tag, msg); break;
|
||||
case 5: listener.onLogW(buildType, tag, msg); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user