我正在尝试使用从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
,这意味着 OnPageStarted
在 OnPageStarted
失败!
此检查在脚本中的 $(document).ready
中完成 .
我在“Android 7.0 for Developers”中找到了这个说明
“从针对Android 7.0的应用开始,当加载新页面时,Javascript上下文将被重置 . 目前,上下文将在新WebView实例中加载的第一页上继承 . 希望将Javascript注入WebView的开发人员应该执行页面开始加载后的脚本 . “
所以尝试在页面开始加载后添加javascript注入代码但是得到了相同的错误 . 也尝试使用 WebView.EvaluateJavascript()
但错误仍然存在 .
如果我将TargetSDK更改为<= 23,则错误消失 .