Android多Webview使用:window.open新开窗口注入JS代码指向原有窗口如何解决?
修复方案
核心原因
你触发JS注入时传入的WebView实例仍为旧的父窗口实例,没有获取到window.open触发创建的新子窗口实例,导致代码被注入到原窗口。
具体修复步骤
- 全局存储子窗口WebView集合
避免用单变量存储子窗口导致多开窗口时实例被覆盖,在Activity中定义全局集合:
// 全局变量,存储所有打开的子窗口WebView private List<WebView> childWebViews = new ArrayList<>();
- 修改
onCreateWindow逻辑
将新创建的子窗口存入集合,同时添加页面加载完成监听,方便控制注入时机:
@Override public boolean onCreateWindow(final WebView view, boolean dialog, boolean userGesture, Message resultMsg) { WebView newWebView = new WebView(MainActivity.this); WebSettings webSettings = newWebView.getSettings(); webSettings.setJavaScriptEnabled(true); webSettings.setSupportMultipleWindows(true); webSettings.setJavaScriptCanOpenWindowsAutomatically(true); webSettings.setDomStorageEnabled(true); webSettings.setAllowFileAccess(true); webSettings.setUserAgentString(dbHelper.getUserConfig().get("userAgent")); newWebView.setFocusable(true); newWebView.setFocusableInTouchMode(true); // 存储子窗口到集合 childWebViews.add(newWebView); newWebView.setWebViewClient(new WebViewClient(){ @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); // 此处可直接触发子窗口的JS注入,也可以存好实例等业务时机触发 } }); newWebView.setWebChromeClient(new WebChromeClient(){ @Override public void onCloseWindow(WebView window) { window.setVisibility(View.GONE); myWebView.removeView(window); // 子窗口关闭时从集合移除,避免内存泄漏 childWebViews.remove(window); } }); myWebView.addView(newWebView); WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj; transport.setWebView(newWebView); resultMsg.sendToTarget(); return true; }
- 调整JS注入调用逻辑
需要向子窗口注入时,从集合中取对应子窗口实例传入webViewEvent方法:
// 示例:向最新打开的子窗口注入JS if (!childWebViews.isEmpty()) { WebView latestChildWebView = childWebViews.get(childWebViews.size() - 1); webViewEvent(latestChildWebView, "你要注入的JS代码", 1000, "service名"); }
注意事项
- 注入时机要晚于子窗口的
onPageFinished回调,否则页面未加载完成,注入的代码会执行失败 - 如果需要区分多个子窗口,可通过
newWebView.setTag()给每个子窗口绑定业务标识,注入时根据Tag匹配对应窗口即可
内容的提问来源于stack exchange,提问作者breadjune
相关产品推荐
相关产品推荐

