我试图调用一些javascript函数坐在运行在一个android webview内的html页面。下面的代码尝试做的很简单——从android应用程序,调用一个带有测试消息的javascript函数,该函数反过来调用一个java函数返回android应用程序,通过toast显示测试消息。
javascript函数如下所示:
function testEcho(message){
window.JSInterface.doEchoTest(message);
}
从WebView,我已经尝试调用javascript如下方式,运气不好:
myWebView.loadUrl("javascript:testEcho(Hello World!)");
mWebView.loadUrl("javascript:(function () { " + "testEcho(Hello World!);" + "})()");
我在WebView上启用了javascript
myWebView.getSettings().setJavaScriptEnabled(true);
// register class containing methods to be exposed to JavaScript
myWebView.addJavascriptInterface(myJSInterface, "JSInterface");
这里是Java类
public class JSInterface{
private WebView mAppView;
public JSInterface (WebView appView) {
this.mAppView = appView;
}
public void doEchoTest(String echo){
Toast toast = Toast.makeText(mAppView.getContext(), echo, Toast.LENGTH_SHORT);
toast.show();
}
}
我花了很多时间在谷歌上搜索,看看我哪里做错了。我找到的所有示例都使用了这种方法。有人发现问题了吗?
编辑:有其他几个外部javascript文件被引用和使用的html,他们会是问题吗?
我创建了一个漂亮的包装器来调用JavaScript方法;它还显示JavaScript错误日志:
private void callJavaScript(String methodName, Object...params){
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("javascript:try{");
stringBuilder.append(methodName);
stringBuilder.append("(");
for (int i = 0; i < params.length; i++) {
Object param = params[i];
if(param instanceof String){
stringBuilder.append("'");
stringBuilder.append(param.toString().replace("'", "\\'"));
stringBuilder.append("'");
}
if(i < params.length - 1){
stringBuilder.append(",");
}
}
stringBuilder.append(")}catch(error){Android.onError(error.message);}");
webView.loadUrl(stringBuilder.toString());
}
你还需要加上这个:
private class WebViewInterface{
@JavascriptInterface
public void onError(String error){
throw new Error(error);
}
}
并添加这个接口到你的webview:
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new WebViewInterface(), "AndroidErrorReporter");
下面是一个从WebView上的资产加载js脚本的例子。
把脚本放到文件中有助于阅读
我在onPageFinished中加载脚本,因为我需要访问脚本中的一些DOM元素(能够访问它应该被加载,否则它将为空)。根据脚本的用途,我们可以更早地加载它
资产/ myjsfile.js
document.getElementById("abc").innerText = "def"
document.getElementById("abc").onclick = function() {
document.getElementById("abc").innerText = "abc"
}
WebViewActivity
webView.settings.javaScriptEnabled = true
webView.webViewClient = object : WebViewClient() {
override fun onPageFinished(view: WebView?, url: String?) {
super.onPageFinished(view, url)
val script = readTextFromAsset("myjsfile.js")
view.loadUrl("javascript: $script")
}
}
fun readTextFromAsset(context: Context, fileName: String): String {
return context.assets.open(fileName).bufferedReader().use { it.readText()
}