OkHttp 之 网络请求耗时统计
OkHttp 3.11.0版本提供了EventListener接口,可以让调用者接收一系列网络请求过程中的事件,例如DNS解析、TSL/SSL连接、Response接收等。通过继承此接口,调用者可以监视整个应用中网络请求次数、流量大小、耗时情况。
使用方法如下:
public class HttpEventListener extends EventListener {
/**
* 自定义EventListener工厂
*/
public static final Factory FACTORY = new Factory() {
final AtomicLong nextCallId = new AtomicLong(1L);
@Override
public EventListener create(Call call) {
long callId = nextCallId.getAndIncrement();
return new HttpEventListener(callId, call.request().url(), System.nanoTime());
}
};
/**
* 每次请求的标识
*/
private final long callId;
/**
* 每次请求的开始时间,单位纳秒
*/
private final long callStartNanos;
private StringBuilder sbLog;
public HttpEventListener(long callId, HttpUrl url, long callStartNanos) {
this.callId = callId;
this.callStartNanos = callStartNanos;
this.sbLog = new StringBuilder(url.toString()).append(" ").append(callId).append(":");
}
private void recordEventLog(String name) {
long elapseNanos = System.nanoTime() - callStartNanos;
sbLog.append(String.format(Locale.CHINA, "%.3f-%s", elapseNanos / 1000000000d, name)).append(";");
if (name.equalsIgnoreCase("callEnd") || name.equalsIgnoreCase("callFailed")) {
//打印出每个步骤的时间点
NearLogger.i(sbLog.toString());
}
}
@Override
public void callStart(Call call) {
super.callStart(call);
recordEventLog("callStart");
}
@Override
public void dnsStart(Call call, String domainName) {
super.dnsStart(call, domainName);
recordEventLog("dnsStart");
}
@Override
public void dnsEnd(Call call, String domainName, List<InetAddress> inetAddressList) {
super.dnsEnd(call, domainName, inetAddressList);
recordEventLog("dnsEnd");
}
@Override
public void connectStart(Call call, InetSocketAddress inetSocketAddress, Proxy proxy) {
super.connectStart(call, inetSocketAddress, proxy);
recordEventLog("connectStart");
}
@Override
public void secureConnectStart(Call call) {
super.secureConnectStart(call);
recordEventLog("secureConnectStart");
}
@Override
public void secureConnectEnd(Call call, @Nullable Handshake handshake) {
super.secureConnectEnd(call, handshake);
recordEventLog("secureConnectEnd");
}
@Override
public void connectEnd(Call call, InetSocketAddress inetSocketAddress, Proxy proxy, @Nullable Protocol protocol) {
super.connectEnd(call, inetSocketAddress, proxy, protocol);
recordEventLog("connectEnd");
}
@Override
public void connectFailed(Call call, InetSocketAddress inetSocketAddress, Proxy proxy, @Nullable Protocol protocol, IOException ioe) {
super.connectFailed(call, inetSocketAddress, proxy, protocol, ioe);
recordEventLog("connectFailed");
}
@Override
public void connectionAcquired(Call call, Connection connection) {
super.connectionAcquired(call, connection);
recordEventLog("connectionAcquired");
}
@Override
public void connectionReleased(Call call, Connection connection) {
super.connectionReleased(call, connection);
recordEventLog("connectionReleased");
}
@Override
public void requestHeadersStart(Call call) {
super.requestHeadersStart(call);
recordEventLog("requestHeadersStart");
}
@Override
public void requestHeadersEnd(Call