这是我用过的整个Java代码。我将在下面详细解释......
public class Test7 extends Activity {
//debug
private final static String TAG = "JSInterface";
private WebView wv;
private class JSInterface {
private WebView wv;
// Variables to manage interfacing with JS
private String returnValue;
private boolean canReadReturnValue;
private Lock lockOnJS;
private Condition condVarOnJS;
public JSInterface (WebView wv) {
this.wv = wv;
this.canReadReturnValue = false;
this.lockOnJS = new ReentrantLock();
this.condVarOnJS = lockOnJS.newCondition();
}
public void setReturnValue(String ret) {
lockOnJS.lock();
returnValue = ret;
canReadReturnValue = true;
condVarOnJS.signal();
lockOnJS.unlock();
Log.d(TAG, "returnValue = " + returnValue);
}
public String getReturnValue() {
Log.d(TAG, "enter in getReturnValue");
lockOnJS.lock();
while (!canReadReturnValue) {
try {
Log.d(TAG, "get wait...");
condVarOnJS.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
lockOnJS.unlock();
Log.d(TAG, "returnValue: " + returnValue);
return returnValue;
}
public String getNewString() {
wv.loadUrl("javascript:JSInterface.setReturnValue(createNewString())");
return getReturnValue();
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
wv = (WebView) findViewById(R.id.webView1);
wv.getSettings().setJavaScriptEnabled(true);
wv.addJavascriptInterface(new JSInterface(wv), "JSInterface");
wv.loadUrl("file:///android_asset/prova7.html");
}
public void button1(View v) {
wv.loadUrl("javascript:func('1')");
}
}
似乎工作正常。
你可以看到我有一个按钮(我们可以调用 button1 ),然后点击它,它会尝试执行一个名为 func()的JS方法
public void button1(View v) {
wv.loadUrl("javascript:func('1')");
}
在这个JS方法中,我必须调用另一个Java方法。这是代码:
function func(id) {
document.getElementById(id).innerHTML = JSInterface.getNewString();
}
我需要将JSInterface.getNewString()的结果返回给innerHTML变量。
JSInterface.getNewString()的代码是这样的:
public String getNewString() {
wv.loadUrl("javascript:JSInterface.setReturnValue(createNewString())");
return getReturnValue();
}
您可以看到我使用方法setReturnValue
和getReturnValue
来返回另一个JS方法返回的值。这是代码:
function createNewString() {
return "my New String";
}
问题是当我尝试设置returnValue时,永远不会执行createNewString函数!如果我添加一个console.log()行,我的logCat什么都不显示!
我无法理解为什么会这样。
答案 0 :(得分:2)
从javascript 调用的所有javascript和JSInterface方法都在Android WebView
的单个线程上运行。所以当你在condVarOnJS.await()
等待时,没有javascript可以被执行,只是因为它是在同一个线程上执行的。
此外,应用程序中的所有webview实例共享相同的javascript线程。
答案 1 :(得分:0)
在Internet Explorer中,我发现了同样的问题。您可以像这样使用setTimeout:
function func(id) {
setTimeout(
function(){
document.getElementById(id).innerHTML = JSInterface.getNewString();
},
500);
}
答案 2 :(得分:0)
我在该代码中执行了您想要的功能,因为我调用了createNewString(),
我将显示我使用的代码,
在java中 ,
public String videoPlay(){
System.out.println("videoPlay");
mWebView.loadUrl("javascript:window.demo.setReturnValue(createNewString())");
return getReturnValue();}
public void setReturnValue(String test){
rotValue=test;
System.out.println(test);
}
public String getReturnValue(){
System.out.println("get"+rotValue);
return rotValue;
}
HTML中的,
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<script>
function inform(){
alert('et');
document.getElementById('myText').value=window.demo.videoPlay();
alert('et');
}
function createNewString() {
return "my New String";
}
</script>
</head>
<body onload="init()">
<form>
<input type='text' id='myText' />
<input type="button" name="test" value="Click me" onclick="inform()">
</form>
</body>
</html>
函数getter和setter调用和值也设置,但我的输出日志为..
11-08 19:18:17.155: INFO/System.out(847): videoPlay
11-08 19:18:17.165: INFO/System.out(847): getnull
11-08 19:18:17.875: INFO/System.out(847): my New String
从JS调用的videoPlay和从java调用的createnewString(),但它在设置之前返回值,因为我没有使用锁的目的是什么,即使我尝试使用锁,就像你为此做的那样它会打印
11-08 19:18:17.155: INFO/System.out(847): videoPlay
11-08 19:18:17.165: INFO/System.out(847): getnull
使用锁也函数回调工作方式错误,需要锁定工作。