You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android多Webview使用:window.open新开窗口注入JS代码指向原有窗口如何解决?

修复方案

核心原因

你触发JS注入时传入的WebView实例仍为旧的父窗口实例,没有获取到window.open触发创建的新子窗口实例,导致代码被注入到原窗口。

具体修复步骤

  1. 全局存储子窗口WebView集合
    避免用单变量存储子窗口导致多开窗口时实例被覆盖,在Activity中定义全局集合:
// 全局变量,存储所有打开的子窗口WebView
private List<WebView> childWebViews = new ArrayList<>();
  1. 修改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;
}
  1. 调整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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 18:15:07