
本文档旨在解决 Android WebView 中 `onCreateWindow` 方法无法直接获取 `window.open()` 打开的新窗口 URL 的问题。通过重写 `WebViewClient` 的 `shouldOverrideUrlLoading` 方法,并结合 `WebChromeClient` 的 `onCreateWindow` 方法,提供了一种可靠的方案来捕获和处理新窗口的 URL,并提供了示例代码和配置说明。
在 Android WebView 开发中,WebChromeClient 的 onCreateWindow 方法用于处理 JavaScript 的 window.open() 调用,创建新的 WebView 窗口。然而,onCreateWindow 方法本身并不直接暴露新窗口的 URL。本文将介绍如何通过结合 WebChromeClient 和 WebViewClient 来获取并处理新窗口的 URL。
解决方案:利用 shouldOverrideUrlLoading 拦截 URL
核心思路是利用 WebViewClient 的 shouldOverrideUrlLoading 方法拦截新窗口的 URL 请求。当 window.open() 被调用时,新的 WebView 会尝试加载 URL,此时 shouldOverrideUrlLoading 方法会被触发,从而可以获取到 URL。
以下是具体的实现步骤:
配置 WebView 设置:
首先,确保 WebView 启用了 JavaScript,并允许 JavaScript 打开新窗口,同时支持多窗口。
webView.apply { settings.javaScriptEnabled = true settings.javaScriptCanOpenWindowsAutomatically = true settings.setSupportMultipleWindows(true)}
实现 WebChromeClient 的 onCreateWindow 方法:
在 onCreateWindow 方法中,创建一个新的 WebView,并设置自定义的 WebViewClient。
webChromeClient = object : WebChromeClient() { override fun onCloseWindow(window: WebView?) { super.onCloseWindow(window) } override fun onCreateWindow( view: WebView?, isDialog: Boolean, isUserGesture: Boolean, resultMsg: Message? ): Boolean { if (view?.context == null) { return false } if (resultMsg == null) { return false } // Use CustomTabs to open the link when the hitTestResult is not null if (view.hitTestResult.extra != null) { val colorParam = CustomTabColorSchemeParams.Builder().setToolbarColor(getColor(context, R.color.blue)).build() val intent = CustomTabsIntent.Builder() .setDefaultColorSchemeParams(colorParam) .setShowTitle(true) .build() intent.launchUrl(view.context, Uri.parse(view.hitTestResult.extra)) return false } // Use a new webViewClient to handle window.open() case val newWebView = WebView(view.context) newWebView.webViewClient = object : WebViewClient() { override fun shouldOverrideUrlLoading( view: WebView?, request: WebResourceRequest? ): Boolean { if (request?.url == null) { return true } val url = request.url.toString() if (url.contains("example.com")) { // Here you can handle “example.com” and do whatever you want return true } return true } } val transport = resultMsg.obj as WebView.WebViewTransport transport.webView = newWebView resultMsg.sendToTarget() return true }}
实现 WebViewClient 的 shouldOverrideUrlLoading 方法:
在自定义的 WebViewClient 中,重写 shouldOverrideUrlLoading 方法。在该方法中,可以获取到新窗口的 URL,并进行相应的处理。
newWebView.webViewClient = object : WebViewClient() { override fun shouldOverrideUrlLoading( view: WebView?, request: WebResourceRequest? ): Boolean { if (request?.url == null) { return true } val url = request.url.toString() if (url.contains("example.com")) { // 在这里处理包含 "example.com" 的 URL // 例如,打开一个新的 Activity 显示该 URL return true } return true }}
代码解释
settings.javaScriptEnabled = true: 启用 JavaScript。settings.javaScriptCanOpenWindowsAutomatically = true: 允许 JavaScript 自动打开窗口。settings.setSupportMultipleWindows(true): 支持多窗口。onCreateWindow: 创建新窗口的回调,在这里创建新的 WebView 并设置 WebViewClient。shouldOverrideUrlLoading: 拦截 URL 加载请求,在这里获取 URL 并进行处理。
注意事项
安全问题: 启用 JavaScript 可能会引入安全风险,需要谨慎处理用户输入和加载的 URL。性能问题: 创建过多的 WebView 可能会影响性能,需要合理管理 WebView 的生命周期。URL 处理: 在 shouldOverrideUrlLoading 方法中,需要根据实际需求处理 URL。可以打开新的 Activity 显示 URL,或者执行其他操作。Context 兼容性: 确保在创建 WebView 时使用正确的 Context,避免内存泄漏。CustomTabs 的使用: 代码中使用了 CustomTabs 来打开链接,需要引入相应的依赖,并处理好兼容性问题。如果 view.hitTestResult.extra 不为空,表示用户点击了链接,此时使用 CustomTabs 打开链接可以提供更好的用户体验。
总结
通过结合 WebChromeClient 的 onCreateWindow 方法和 WebViewClient 的 shouldOverrideUrlLoading 方法,可以有效地获取并处理 Android WebView 中 window.open() 打开的新窗口 URL。这种方法简单易用,可以满足大多数场景的需求。在实际应用中,需要根据具体情况进行调整和优化,以确保安全性和性能。
以上就是获取 Android WebView 新窗口 URL 的正确方法的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1531328.html
微信扫一扫
支付宝扫一扫