我正在尝试使用从App到Android WebView的函数注入一个javascript命名空间

NOTE: 除了以下脚本之外,我对WebView上加载的实际源没有任何控制权 . 我在Xamarin工作,所以Android代码是C#

所以我使用了两个主要组件:

(function() {
    console.log("Loading JS Bindings");
    function addOnClickHandler () {
        $(document).ready(function () {
            if (window.InjectedNamespace) { // check InjectedNamespace namespace exists
                var onClickHandler = window.InjectedNamespace.handleOnClick;
                if (typeof onClickHandler === 'function') {
                    $(":button, a").each(function (idx) {
                        $(this).click(function() {
                            onClickHandler("click!");
                        });
                    });
                } else {
                    console.error('missing onclick handler');
                }
            } else {
                console.error('missing InjectedNamespace namespace');
            }
        });
    }
})();
  • 以上将由第三方添加的脚本,它将 click 函数附加到所有 <button><a> 标记 .

  • 以下命名空间将从App端注入

var InjectedNamespace={handleOnClick:function(a){Internal.handleOnClickEvent(a)}};

在App方面,我有这个Javascript接口对象

class JSInterfaceObject : Java.Lang.Object
    {
      readonly CustomWebView View;
      string Data;

      public JSInterfaceObject(CustomWebView view)
      {
        View = view;
      }

      [Export]
      [JavascriptInterface]
      // only methods exposed with annotation [JavascriptInterface] are exposed to javascript
      public void handleOnClickEvent(string data)
      {
        Log.ForContext("TAG", TAG).Debug("handleOnClickEvent: " + data);
        if(View.OnClick != null)
        {
          View.OnClick(data);
        }
      }
    }

并且此界面将添加到webview使用

AddJavascriptInterface(new JSInterfaceObject(this), "Internal");

OnPageStarted 我正在使用javascript注入

webview.LoadUrl("javascript:"+"var IM={handleOnClick:function(a){Internal.handleOnClickEvent(a)}};");

此设置适用于Android SDK <24 . 但对于SDK>中的Webview> = 24,脚本始终错误输出 missing InjectedNamespace namespace ,这意味着 OnPageStartedOnPageStarted 失败!

此检查在脚本中的 $(document).ready 中完成 .

我在“Android 7.0 for Developers”中找到了这个说明

“从针对Android 7.0的应用开始,当加载新页面时,Javascript上下文将被重置 . 目前,上下文将在新WebView实例中加载的第一页上继承 . 希望将Javascript注入WebView的开发人员应该执行页面开始加载后的脚本 . “

所以尝试在页面开始加载后添加javascript注入代码但是得到了相同的错误 . 也尝试使用 WebView.EvaluateJavascript() 但错误仍然存在 .

如果我将TargetSDK更改为<= 23,则错误消失 .