Android okhttp 网络链接各阶段监控

embedded/2024/12/28 3:55:09/

步骤 1: 添加依赖

在项目的 build.gradle 文件中,添加 OkHttp 依赖:

implementation 'com.squareup.okhttp3:okhttp:4.11.0'

步骤 2: 创建自定义的 EventListener

创建一个自定义的 EventListener 类:

import android.util.Log
import okhttp3.*
import java.io.IOException
import java.net.InetAddress
import java.net.InetSocketAddress
import java.net.Proxyclass LoggingEventListener : EventListener() {private var mCallStartTime: Long? = nullprivate var mCallEndTime: Long? = nullprivate var mDnsStartTime: Long? = nullprivate var mDnsEndTime: Long? = nullprivate var mConnectStartTime: Long? = nullprivate var mSecureConnectStartTime: Long? = nullprivate var mSecureConnectEndTime: Long? = nullprivate var mConnectEndTime: Long? = nullprivate var mRequestHeadersStartTime: Long? = nullprivate var mRequestHeadersEndTime: Long? = nullprivate var mResponseHeadersStartTime: Long? = nullprivate var mResponseHeadersEndTime: Long? = nullprivate var mResponseBodyStartTime: Long? = nullprivate var mResponseBodyEndTime: Long? = nullcompanion object {const val TAG = "LoggingEventListener"}override fun callStart(call: Call) {mCallStartTime = System.currentTimeMillis()Log.i(TAG, "Event callStart at $mCallStartTime")}override fun dnsStart(call: Call, domainName: String) {mDnsStartTime = System.currentTimeMillis()Log.i(TAG, "Event dnsStart at $mDnsStartTime")}override fun dnsEnd(call: Call, domainName: String, inetAddressList: List<InetAddress>) {mDnsEndTime = System.currentTimeMillis()Log.i(TAG, "Event dnsEnd at $mDnsEndTime dnsDuration is ${mDnsEndTime!! - mDnsStartTime!!} ms")}override fun connectStart(call: Call, inetSocketAddress: InetSocketAddress, proxy: Proxy) {mConnectStartTime = System.currentTimeMillis()Log.i(TAG, "Event connectStart at $mConnectStartTime")}override fun secureConnectStart(call: Call) {mSecureConnectStartTime = System.currentTimeMillis()Log.i(TAG, "Event secureConnectStart at $mSecureConnectStartTime")}override fun secureConnectEnd(call: Call, handshake: Handshake?) {mSecureConnectEndTime = System.currentTimeMillis()Log.i(TAG, "Event secureConnectEnd at $mSecureConnectEndTime secureConnectDuration is ${mSecureConnectEndTime!! - mSecureConnectStartTime!!} ms")}override fun connectEnd(call: Call, inetSocketAddress: InetSocketAddress, proxy: Proxy, protocol: Protocol?) {mConnectEndTime = System.currentTimeMillis()Log.i(TAG, "Event connectEnd at $mConnectEndTime ConnectDuration is ${mConnectEndTime!! - mConnectStartTime!!} ms")}override fun requestHeadersStart(call: Call) {mRequestHeadersStartTime = System.currentTimeMillis()Log.i(TAG, "Event requestHeadersStart at $mRequestHeadersStartTime")}override fun requestHeadersEnd(call: Call, request: Request) {mRequestHeadersEndTime = System.currentTimeMillis()Log.i(TAG, "Event requestHeadersEnd at $mRequestHeadersEndTime requestHeadersDuration is ${mRequestHeadersEndTime!! - mRequestHeadersStartTime!!} ms")}override fun responseHeadersStart(call: Call) {mResponseHeadersStartTime = System.currentTimeMillis()Log.i(TAG, "Event responseHeadersStart at $mResponseHeadersStartTime")}override fun responseHeadersEnd(call: Call, response: Response) {mResponseHeadersEndTime = System.currentTimeMillis()Log.i(TAG, "Event responseHeadersEnd at $mResponseHeadersEndTime responseHeadersDuration is ${mResponseHeadersEndTime!! - mResponseHeadersStartTime!!} ms")}override fun responseBodyStart(call: Call) {mResponseBodyStartTime = System.currentTimeMillis()Log.i(TAG, "Event responseBodyStart at $mResponseBodyStartTime")}override fun responseBodyEnd(call: Call, byteCount: Long) {mResponseBodyEndTime = System.currentTimeMillis()Log.i(TAG, "Event responseBodyEnd at $mResponseBodyEndTime responseHeadersDuration is ${mResponseBodyEndTime!! - mResponseBodyStartTime!!} ms")}override fun callEnd(call: Call) {mCallEndTime = System.currentTimeMillis()Log.i(TAG, "Event callEnd at $mCallEndTime responseHeadersDuration is ${mCallEndTime!! - mCallStartTime!!} ms")}override fun callFailed(call: Call, ioe: IOException) {Log.i(TAG,"Request Failed: ${ioe.message}")}
}

步骤 3: 在 MainActivity 中发起网络请求

创建一个简单的 MainActivity,发起 HTTP 请求并使用 LoggingEventListener

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import okhttp3.*
import java.io.IOExceptionclass MainActivity : AppCompatActivity() {companion object {const val TAG = "MainActivity"}override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)// 创建 OkHttpClient 并设置自定义 EventListenerval client = OkHttpClient.Builder().eventListener(LoggingEventListener()).build()// 创建请求对象val request = Request.Builder().url("https://jsonplaceholder.typicode.com/posts/1") // 示例 API.build()// 发起异步网络请求client.newCall(request).enqueue(object : Callback {override fun onFailure(call: Call, e: IOException) {Log.i(TAG, "Request Failed: ${e.message}")}override fun onResponse(call: Call, response: Response) {Log.i(TAG, "Response: ${response.body?.string()}")}})}
}

步骤 4: 添加权限

AndroidManifest.xml 中添加网络权限:

<uses-permission android:name="android.permission.INTERNET" />

步骤 5: 布局文件

创建简单的布局文件 activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:gravity="center"android:padding="16dp"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="OkHttp EventListener Demo"android:textSize="18sp"android:textStyle="bold" />
</LinearLayout>

运行结果

运行应用后,打开日志工具(Logcat)可以看到网络请求的各个阶段日志,例如:

I/LoggingEventListener: Event callStart at 1731855030207
I/LoggingEventListener: Event dnsStart at 1731855030212
I/LoggingEventListener: Event dnsEnd at 1731855030213 dnsDuration is 1 ms
I/LoggingEventListener: Event connectStart at 1731855030215
I/LoggingEventListener: Event secureConnectStart at 1731855030581
I/LoggingEventListener: Event secureConnectEnd at 1731855030878 secureConnectDuration is 297 ms
I/LoggingEventListener: Event connectEnd at 1731855030886 ConnectDuration is 671 ms
I/LoggingEventListener: Event requestHeadersStart at 1731855030887
I/LoggingEventListener: Event requestHeadersEnd at 1731855030889 requestHeadersDuration is 2 ms
I/LoggingEventListener: Event responseHeadersStart at 1731855031406
I/LoggingEventListener: Event responseHeadersEnd at 1731855031406 responseHeadersDuration is 0 ms
I/LoggingEventListener: Event responseBodyStart at 1731855031414
I/LoggingEventListener: Event responseBodyEnd at 1731855031415 responseHeadersDuration is 1 ms
I/LoggingEventListener: Event callEnd at 1731855031415 responseHeadersDuration is 1208 ms


http://www.ppmy.cn/embedded/149351.html

相关文章

【漏洞复现】灵当CRM datapdf.php 任意文件读取漏洞

免责声明 请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,作者不为此承担任何责任。工具来自网络,安全性自测,如有侵权请联系删除。本次测试仅供学习使用,如若非法他用,与平台和本文作…

Kafka、RocketMQ、RabbitMQ 对比

面试中对 Kafka 、 RocketMQ 、和 RabbitMQ 的对比是常见问题&#xff0c;可以从以下几个维度进行分析&#xff1a; 1️⃣ 基础概念 特性KafkaRocketMQRabbitMQ开发语言Java ScalaJavaErlang定位分布式流处理平台分布式消息中间件高效、可靠的消息队列消息模型Topic &#xf…

信息抽取(NLP)是什么技术有哪些应用?

信息抽取是将非结构化的信息转化为结构化信息的过程。一般应用于电商平均分析、知识图谱和大模型训练。 不同模型的对比 1. 规则模型 优点 简单直观:基于人工设定的规则,不需要大量的数据集进行训练,只要规则制定者对目标信息有清晰的理解即可开始构建。例如,对于一些具有…

taro中实现带有途径点的路径规划

前言 taro中实现带有途径点的路径规划 import React, {useState, useEffect} from "react"; import {View, Map, ScrollView} from tarojs/components import Taro, {useRouter} from tarojs/taro; import request from ../../request; import api from ../../reque…

Spring Boot 中 Map 的最佳实践

在Spring Boot中使用Map时&#xff0c;请遵循以下最佳实践: 1.避免在Controller中 直接使用Map。应该使用RequestBody 接收-个DTO对象或者 RequestParam接收参数&#xff0c;然后在Service中处 理Map。 2.避免在Service中 直接使用原始的Map。应该使用Autowired 注入-个专门…

elementUI——upload限制图片或者文件只能上传一个——公开版

最近在写后台管理系统时&#xff0c;遇到一个需求&#xff0c;就是上传图片&#xff0c;有且仅能上传一张。 效果图如下&#xff1a; 功能描述&#xff1a;上传图片时&#xff0c;仅支持单选&#xff0c;如果上传图片成功后&#xff0c;展示图片&#xff0c;并隐藏添加图片的…

Linux shell脚本用于常见图片png、jpg、jpeg、webp、tiff格式批量转PDF文件

Linux Debian12基于ImageMagick图像处理工具编写shell脚本用于常见图片png、jpg、jpeg、webp、tiff格式批量转PDF文件&#xff0c;”多个图片分开生成多个PDF文件“或者“多个图片合并生成一个PDF文件” BiliBili视频链接&#xff1a; Linux shell脚本对常见图片格式批量转换…

Qt笔记:网络编程UDP

一、铺垫 1.Qt框架使用的网络结构的基础就是Linux学习的网络编程基础&#xff1b;所以使用Qt写客户端&#xff0c;使用Linux写服务端&#xff1b;两者是可以实现互联的 二、UDP 网络编程UDP使用套路&#xff1a; 1.首先在.pro文件中加上network&#xff0c;使Qt可以搭载网络…