将JavaScript匿名函数作为参数传递给WebView

4

我有一个本地应用程序,在其中包含了一个WebView控件。 我添加了一个类到WebView中,以便能够从JavaScript中进行调用,如下所示:

webView.addJavascriptInterface(new JavascriptInterface(webView, handler), "Android.JSI");

我随后从JavaScript调用JavaScriptInterface类。我的HTML/JavaScript代码如下:

<input type="button" value="Sleep Alert" onclick="sleepAlert(sleepAlertCallbackSuccess, sleepAlertCallbackFail, 'Hi Sleep Alert');" />

function sleepAlert(callBackSuccess, callBackFailure, message)
{                       
    window.Android.JSI.sleepAlert(callBackSuccess.name, callBackFailure.name, message);
}

function sleepAlertCallbackSuccess(message)
{
    alert("success: " + message);
}

function sleepAlertCallbackFail(message)
{
    alert("fail: " + message);
}

I then callback into the JavaScript like so:

js = "javascript:" + callbackSuccess + "('" + message + "')";
webView.loadUrl(js);

这个方案可行,但如果用户想传递匿名函数而不是普通的命名函数,我就有些困惑了。例如:

<input type="button" value="Anonymous call back" onclick="sleepAlert(function(message) { alert(message); }, sleepAlertCallbackFail, 'anonymous sleep alert');" />

当我将其传递给我的Java类时
public void sleepAlert(final String callbackSuccess, String callbackFail, final String message)

它说callbackSuccess未定义。

有什么正确的方法可以做到这一点,因为我感觉自己正在走错的路?

1个回答

1

将其设置为变量。您可以这样做:

var a = <whatever>; a(message);

如果它是一个方法,它将解析为:

var a = sleepAlertCallbackSuccess; a(message);

或者如果它是匿名的:

var a = function(message) { ... }; a(message);

由于你是在地址栏中传递它,所以你需要对它进行URI编码等操作,但这种方法应该是可行的。

更新:

这是我想表达的大致意思:

js = "javascript: var a=" + callbackSuccess + ";a(message);";
String url = "javascript:" + Uri.encode(js);
webView.loadUrl(url);

现在你可以给它类似于 "function(message) { alert(message); }" 这样的东西,它就能工作了。顺便说一句,我会非常小心地让用户在这里运行任意代码。很难说没有看到更多的情况下,但这种做法很容易导致安全漏洞的暴露。

我不确定是否理解了。回调函数已经是sleepAlert中的一个变量了吗? - Greg Randall
更新以给你一个例子 - kabuko
@GregRandall 传递给Java的回调函数字符串总是“未定义”。您是否遇到过这个问题? - James Zhao

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接