如何在Android WebView中用Firebase Performance Monitoring追踪网络请求?
解决WebView网络请求不显示在Firebase Performance Monitoring的问题
嘿,这个问题我之前踩过坑!Firebase Performance Monitoring默认确实不会自动追踪WebView内部的网络请求——因为WebView用的是独立的系统网络栈,和App里的OkHttp/HttpURLConnection不共享。不过只需要几行关键代码就能搞定,不用大动干戈,还能自动追踪响应时间、payload大小、成功率这些核心指标。
核心思路
让WebView的所有网络请求通过带Firebase性能拦截器的OkHttp来发起,这样Firebase就能自动捕获并上报所有请求指标,无需手动埋点。
具体步骤
1. 确认依赖配置
首先确保你的app/build.gradle里已经添加了必要的依赖(用最新版本即可):
// Firebase Performance Monitoring implementation 'com.google.firebase:firebase-perf-ktx' // OkHttp 网络库 implementation 'com.squareup.okhttp3:okhttp:4.11.0' // 可选:同步WebView和OkHttp的Cookie,避免请求因Cookie缺失失败 implementation 'com.github.franmontiel:PersistentCookieJar:v1.0.1'
2. 自定义WebViewClient,用OkHttp接管请求
创建一个自定义的WebViewClient,让它用带Firebase拦截器的OkHttp来处理WebView的所有请求:
class OkHttpWebViewClient(private val webView: WebView) : WebViewClient() { // 初始化带Firebase拦截器的OkHttp客户端 private val okHttpClient: OkHttpClient by lazy { OkHttpClient.Builder() // 添加Firebase性能拦截器,自动追踪请求指标 .addInterceptor(FirebasePerformanceInterceptor()) // 同步WebView的Cookie(可选但关键,否则部分请求会失败) .cookieJar(object : CookieJar { override fun saveFromResponse(url: HttpUrl, cookies: List<Cookie>) { val cookieManager = CookieManager.getInstance() cookies.forEach { cookie -> cookieManager.setCookie(url.toString(), cookie.toString()) } } override fun loadForRequest(url: HttpUrl): List<Cookie> { val cookieManager = CookieManager.getInstance() val cookies = cookieManager.getCookie(url.toString()) ?: return emptyList() return Cookie.parseAll(url, cookies) } }) .build() } override fun shouldInterceptRequest( view: WebView?, request: WebResourceRequest? ): WebResourceResponse? { request ?: return super.shouldInterceptRequest(view, request) val url = request.url.toString() // 可选:只追踪特定域名的请求,比如你的业务域名 if (!url.startsWith("https://your-business-domain.com")) { return super.shouldInterceptRequest(view, request) } // 构建OkHttp请求,复制WebView的请求方法、头信息和body val okHttpRequest = Request.Builder() .url(url) .method(request.method, request.body?.let { RequestBody.create(MediaType.parse(request.mimeType), it) }) .apply { request.requestHeaders.forEach { (key, value) -> addHeader(key, value) } } .build() return try { // 发起请求并转换为WebResourceResponse返回给WebView val response = okHttpClient.newCall(okHttpRequest).execute() WebResourceResponse( response.header("Content-Type")?.split(";")?.firstOrNull(), response.header("Content-Encoding"), response.code, response.message, response.headers.toMultimap().mapValues { it.value.joinToString(",") }, response.body?.byteStream() ) } catch (e: Exception) { e.printStackTrace() // 请求失败时交给WebView默认处理 super.shouldInterceptRequest(view, request) } } }
3. 给WebView设置自定义Client
在初始化WebView的地方,替换默认的WebViewClient为我们自定义的:
// 初始化WebView val webView = findViewById<WebView>(R.id.web_view) webView.settings.apply { javaScriptEnabled = true domStorageEnabled = true // 根据你的需求添加其他WebView配置 } // 设置自定义WebViewClient webView.webViewClient = OkHttpWebViewClient(webView) // 加载目标URL webView.loadUrl("https://your-target-url.com")
4. 验证效果
打开Firebase Performance Monitoring控制台的Network标签页,等待几分钟(调试模式下数据会实时上传),你就能看到WebView里所有请求的详细指标了:
- 响应时间(Request Duration)
- 请求/响应Payload大小
- 成功率(Success Rate)
- 状态码分布
如果想实时调试,可以在Logcat里搜索FirebasePerformance,会看到类似Logging network request metric for URL: xxx的日志,说明指标正在被正确捕获。
注意事项
- 确保已经在
AndroidManifest.xml中添加了网络权限:<uses-permission android:name="android.permission.INTERNET" /> - 如果不需要追踪所有请求,记得在
shouldInterceptRequest里添加域名过滤逻辑,避免不必要的性能开销 - 调试模式下,Firebase Perf的日志会更详细,可以通过
adb shell setprop debug.firebase.perf.logcat enable开启更详细的日志
内容的提问来源于stack exchange,提问作者Slick Slime
相关产品推荐
相关产品推荐

