Android WebView如何让根URL请求映射到assets目录?
解决方案
可以通过修改WebView的请求拦截逻辑,实现根URL到assets目录的映射,不用改动网页代码,下面提供两种可行方案:
方案1:自定义AssetPathHandler扩展WebViewAssetLoader
WebViewAssetLoader支持自定义路径处理器,你可以创建一个处理根路径的Handler,把所有根目录的请求映射到assets目录:
// 自定义根路径处理器 class RootAssetPathHandler(private val context: Context) : WebViewAssetLoader.AssetPathHandler() { override fun handle(path: String): WebResourceResponse? { // 根路径请求(比如/js/util.js),拼接成assets目录下的路径 val assetPath = "assets$path" return try { val inputStream = context.assets.open(assetPath) val mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension( MimeTypeMap.getFileExtensionFromUrl(path) ) WebResourceResponse(mimeType, "UTF-8", inputStream) } catch (e: IOException) { null // 找不到资源时返回null,让WebView处理错误 } } }
然后初始化WebViewAssetLoader时添加这个处理器,匹配根路径:
val assetLoader = WebViewAssetLoader.Builder() .addPathHandler("/", RootAssetPathHandler(context)) // 根路径映射到自定义handler .addPathHandler("/assets/", WebViewAssetLoader.AssetsPathHandler(context)) // 保留原assets路径支持 .build() // 设置WebViewClient webView.webViewClient = object : WebViewClientCompat() { override fun shouldInterceptRequest( view: WebView, request: WebResourceRequest ): WebResourceResponse? { return assetLoader.shouldInterceptRequest(request.url) } } // 加载首页 webView.loadUrl("https://appassets.androidplatform.net/assets/index.html")
方案2:通过WebViewClient拦截并重写请求路径
如果不想自定义PathHandler,也可以直接在shouldInterceptRequest里修改请求URL:
val assetLoader = WebViewAssetLoader.Builder() .addPathHandler("/assets/", WebViewAssetLoader.AssetsPathHandler(context)) .build() webView.webViewClient = object : WebViewClientCompat() { override fun shouldInterceptRequest( view: WebView, request: WebResourceRequest ): WebResourceResponse? { val url = request.url.toString() // 判断是否是根目录的请求(比如https://appassets.androidplatform.net/js/util.js) if (url.startsWith("https://appassets.androidplatform.net/") && !url.startsWith("https://appassets.androidplatform.net/assets/")) { // 重写URL,添加assets前缀 val modifiedUrl = url.replace("https://appassets.androidplatform.net/", "https://appassets.androidplatform.net/assets/") return assetLoader.shouldInterceptRequest(Uri.parse(modifiedUrl)) } return assetLoader.shouldInterceptRequest(request.url) } } webView.loadUrl("https://appassets.androidplatform.net/assets/index.html")
注意事项
- 确保你已经依赖了
androidx.webkit:webkit库,WebViewAssetLoader需要这个依赖支持。 - 两种方案都能让根路径的请求自动映射到assets目录下,不用修改网页里的相对URL。
内容的提问来源于stack exchange,提问作者Gaboros
相关产品推荐
相关产品推荐

