EventListener.Factory监听网络请求全过程
网上介绍的并不多,关于它的使用方式,可能会存在很多坑。
主要是为了监听网络请求过程。
首先OkHttpClient.Builder.eventListenerFactory需要的是一个实现了EventListener接口的工厂类。
简单的实现方式。
public class HttpEventListener extends EventListener {
private final long callId;
final AtomicLong nextCallId = new AtomicLong(1L);
@Override
public EventListener create(Call call) {
long callId = nextCallId.getAndIncrement();
return new HttpEventListener(callId, System.nanoTime());
}
public HttpEventListener(long callId, long callStartNanos) {
this.callId = callId;
this.callStartNanos = callStartNanos;
}
private long dnsStartTime;
private long dnsParseTime;
@Override
public void dnsStart(Call call, String domainName) {
super.dnsStart(call, domainName);
dnsStartTime = System.nanoTime();
}
@Override
public void dnsEnd(Call call, String domainName, List<InetAddress> inetAddressList) {
super.dnsEnd(call, domainName, inetAddressList);
dnsParseTime = System.nanoTime() - dnsStartTime;//dns解析耗时
}
//自动补全剩余实现方法
}
EventListener.create方法在okHttpClient.newCall后执行
dnsParseTime可以算出dns解析耗时,还可以监听每次dns解析的domain,解析的结果inetAddressList。
这个是比较好用的。
问题是如何将这些数据回传回来呢
在OkHttpClient构造时传入自定义参数
OkHttpClient.Builder builder = new OkHttpClient.Builder();
final ResponseTag tag = new ResponseTag();
tag.logHandler = logHandler;
httpClient.newCall(requestBuilder.tag(tag).build()).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
}
});
//自动补全剩余实现方法
public class HttpEventListener extends EventListener {
/**
* 每次请求的标识
*/
private long callId = 1L;
/**
* 每次请求的开始时间,单位纳秒
*/
private final long callStartNanos;
private long total_elapsed_time;
private long dns_elapsed_time;
private long connect_elapsed_time;
private long tls_connect_elapsed_time;
private long request_elapsed_time;
private long wait_elapsed_time;
private long response_elapsed_time;
private Client.ResponseTag responseTag;
private LogHandler logHandler;
private long start_dns_elapsed_time;
private long start_total_elapsed_time;
private long start_connect_elapsed_time;
private long start_tls_connect_elapsed_time;
private long start_request_elapsed_time;
private long start_response_elapsed_time;
public HttpEventListener(long callId, Client.ResponseTag responseTag, long callStartNanos) {
this.callId = callId;
this.callStartNanos = callStartNanos;
this.responseTag = responseTag;
this.logHandler = responseTag.logHandler;
}
public static final Factory FACTORY = new Factory() {
final AtomicLong nextCallId = new AtomicLong(1L);
@Override
public EventListener create(@NotNull Call call) {
long callId = nextCallId.getAndIncrement();
return new HttpEventListener(callId, (Client.ResponseTag) call.request().tag(), System.nanoTime());
}
};
@Override
public void callStart(Call call) {
super.callStart(call);
start_total_elapsed_time = System.currentTimeMillis();
}
@Override
public void dnsStart(Call call, String domainName) {
super.dnsStart(call, domainName);
start_dns_elapsed_time = System.currentTimeMillis();
}
@Override
public void dnsEnd(Call call, String domainName, List<InetAddress> inetAddressList) {
super.dnsEnd(call, domainName, inetAddressList);
dns_elapsed_time = System.currentTimeMillis() - start_dns_elapsed_time;//dns解析耗时
logHandler.send("dns_elapsed_time", dns_elapsed_time);
}
@Override
public void connectStart(Call call, InetSocketAddress inetSocketAddress, Proxy proxy) {
super.connectStart(call, inetSocketAddress, proxy);
start_connect_elapsed_time = System.currentTimeMillis();
}
@Override
public void secureConnectStart(Call call) {
super.secureConnectStart(call);
start_tls_connect_elapsed_time = System.currentTimeMillis();
}
@Override
public void secureConnectEnd(Call call, Handshake handshake) {
super.secureConnectEnd(call, handshake);
tls_connect_elapsed_time = System.currentTimeMillis() - start_tls_connect_elapsed_time;
logHandler.send("tls_connect_elapsed_time", tls_connect_elapsed_time);
}
@Override
public void connectEnd(Call call, InetSocketAddress inetSocketAddress, Proxy proxy, Protocol protocol) {
super.connectEnd(call, inetSocketAddress, proxy, protocol);
connect_elapsed_time = System.currentTimeMillis() - start_connect_elapsed_time;
logHandler.send("connect_elapsed_time", connect_elapsed_time);
}
@Override
public void connectFailed(Call call, InetSocketAddress inetSocketAddress, Proxy proxy, Protocol protocol, IOException ioe) {
super.connectFailed(call, inetSocketAddress, proxy, protocol, ioe);
}
@Override
public void connectionAcquired(Call call, Connection connection) {
super.connectionAcquired(call, connection);
}
@Override
public void connectionReleased(Call call, Connection connection) {
super.connectionReleased(call, connection);
}
@Override
public void requestHeadersStart(Call call) {
super.requestHeadersStart(call);
start_request_elapsed_time = System.currentTimeMillis();
}
@Override
public void requestHeadersEnd(Call call, Request request) {
super.requestHeadersEnd(call, request);
}
@Override
public void requestBodyStart(Call call) {
super.requestBodyStart(call);
}
@Override
public void requestBodyEnd(Call call, long byteCount) {
super.requestBodyEnd(call, byteCount);
request_elapsed_time = System.currentTimeMillis() - start_request_elapsed_time;
logHandler.send("request_elapsed_time", request_elapsed_time);
}
@Override
public void responseHeadersStart(Call call) {
super.responseHeadersStart(call);
start_response_elapsed_time = System.currentTimeMillis();
}
@Override
public void responseHeadersEnd(Call call, Response response) {
super.responseHeadersEnd(call, response);
}
@Override
public void responseBodyStart(Call call) {
super.responseBodyStart(call);
}
@Override
public void responseBodyEnd(Call call, long byteCount) {
super.responseBodyEnd(call, byteCount);
response_elapsed_time = System.currentTimeMillis() - start_response_elapsed_time;
wait_elapsed_time = System.currentTimeMillis() - start_request_elapsed_time;
logHandler.send("response_elapsed_time", response_elapsed_time);
logHandler.send("wait_elapsed_time", wait_elapsed_time);
}
@Override
public void callEnd(Call call) {
super.callEnd(call);
total_elapsed_time = System.currentTimeMillis() - start_total_elapsed_time;
logHandler.send("total_elapsed_time", total_elapsed_time);
}
@Override
public void callFailed(Call call, IOException ioe) {
super.callFailed(call, ioe);
}
}
//利用反射将logHandler打回来的数据存到对象
public static LogHandler getUplogHandler(final Object obj) {
final String setMethod = "set";
LogHandler logHandler = new LogHandler() {
@Override
public void send(String key, Object value) {
try {
if (value instanceof String) {
Method setByKey = obj.getClass().getMethod(setMethod + StringUtils.upperCase(key), Class.forName("java.lang.String"));
setByKey.invoke(obj, value);
} else if (value instanceof Integer) {
Method setByKey = obj.getClass().getMethod(setMethod + StringUtils.upperCase(key), int.class);
setByKey.invoke(obj, value);
} else if (value instanceof Long) {
Method setByKey = obj.getClass().getMethod(setMethod + StringUtils.upperCase(key), long.class);
setByKey.invoke(obj, value);
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
@Override
public Object getUploadInfo() {
return obj;
}
};
return logHandler;
}