Android WebView拦截localhost重定向URL替换为file协议本地资源加载失败问询
问题根因
你当前的逻辑写在onPageFinished回调中,该回调是WebView完成URL加载(包括加载失败)后才会触发,此时https://localhost:8080/开头的请求已经发送并因为本地没有对应服务返回ERR_CONNECTION_REFUSED错误,后续的替换加载逻辑生效时机太晚,还会和已失败的加载请求产生冲突。
修复方案
你需要在URL加载前的拦截回调shouldOverrideUrlLoading中处理重定向替换逻辑,避免原localhost请求先发送失败。
修正后的代码示例
class ConfigWeatherStationFragment : Fragment(), BleManagerListener { private val webViewClient = object : WebViewClient() { // 兼容Android 7.0及以上版本的URL拦截 override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean { return handleUrlIntercept(request?.url.toString(), view) } // 兼容Android 7.0以下版本的URL拦截 override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean { return handleUrlIntercept(url, view) } override fun onPageFinished(view: WebView, url: String?) { super.onPageFinished(view, url) binding.configWsPBar.visibility = ProgressBar.GONE Log.i("Loaded", url ?: "空地址") } // 统一处理拦截逻辑 private fun handleUrlIntercept(url: String?, view: WebView?): Boolean { if (url.isNullOrEmpty()) return false // 匹配目标重定向地址 if (url.startsWith("https://localhost:8080/")) { Log.i("WS", "拦截到重定向地址,替换为本地资源") // 注意本地assets资源的标准前缀为file:///android_asset/,请根据你的实际文件存放路径调整 val localResourceUrl = url.replace("https://localhost:8080/", "file:///android_asset/") view?.loadUrl(localResourceUrl) // 返回true表示已自行处理该URL,WebView不再加载原地址 return true } // 其他地址走默认加载逻辑 return false } } // 原有onCreate、onCreateView等逻辑保持不变 override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) bleManager.writeMessage(BleManager.FUNCTION_WEATHER_STATION, BleManager.WEATHER_STATION_REQUEST) } override fun onReadData(data: String) { // BleManagerListener Log.i("WS", data) if(URLUtil.isValidUrl(data)) { askAuthorisation(data) } else { TODO("Process the acknowledgement") } } private fun askAuthorisation(url: String) { var webView = binding.configWsWeb webView.post(Runnable { webView.settings.allowContentAccess = true webView.settings.allowFileAccess = true // 如果本地页面需要JS交互,添加下面这行配置 // webView.settings.javaScriptEnabled = true webView.webViewClient = webViewClient webView.loadUrl(url) }) } }
额外注意项
- 请确认你的本地HTML资源存放在项目
src/main/assets目录下,若存放在其他路径,请对应调整替换后的file:///前缀。 - 若本地页面需要使用JavaScript能力,请在WebView配置中开启
javaScriptEnabled = true。
内容的提问来源于stack exchange,提问作者Dark Patate
相关产品推荐
相关产品推荐

