我想在我的Android应用程序中对某些Java代码进行同步调用。
我正在使用此解决方案: https://stackoverflow.com/a/3338656
我的Java代码:
final class MyWebChromeClient extends WebChromeClient {
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
Log.d("LogTag", message);
result.confirm();
return true;
}
}
我的JavaScript代码:
<html>
<script>
function java_request(){
alert('test');
}
</script>
<body>
<h2>Welcome</h2>
<div id="area"></div>
<form>
<input type="button" value="java_call" onclick="java_request()">
</form>
</body>
</html>
当我点击java_call
按钮时,按钮会进入按下状态。我可以在控制台日志中看到'test'
。直到这里一切都很正常。
问题是,按钮永远不会恢复到正常状态。它保持在按下状态。也许JavaScript执行被破坏了?
为什么按钮永远不会恢复正常状态?
答案 0 :(得分:95)
我认为这不是让javascript执行java代码的最佳解决方案。见这里:
如果要将本机代码公开给可通过javascript调用的HTML,请在Web视图声明周围执行以下操作:
JavaScriptInterface jsInterface = new JavaScriptInterface(this);
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(jsInterface, "JSInterface");
声明课程JavaScriptInterface
:
public class JavaScriptInterface {
private Activity activity;
public JavaScriptInterface(Activity activity) {
this.activity = activity;
}
@JavascriptInterface
public void startVideo(String videoAddress){
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse(videoAddress), "video/3gpp");
activity.startActivity(intent);
}
}
我宣布播放视频的单一功能,但你可以做任何你想做的事。
最后,您可以通过简单的javascript调用在WebView
内容中调用此内容:
<video width="320" height="240" controls="controls" poster='poster.gif'
onclick="window.JSInterface.startVideo('file:///sdcard/test.3gp');" >
Your browser does not support the video tag.
</video>
这个例子取自我的另一个答案,关于播放视频,但应该足够解释。
编辑根据@ CedricSoubrie的评论:如果应用程序的目标版本设置为17或更高,则需要在要导出到Web的每个方法上方添加注释@JavascriptInterface
图。
答案 1 :(得分:1)
您的函数返回'true'。这使得HTML代码的“onclick”属性等于true,因此按钮仍然被“点击”。
答案 2 :(得分:1)
&#34; YourJavaScriptInterface &#34;中定义的方法上课时,不要忘记使用&#34; @ JavascriptInterface&#34;来注释要公开的每个方法,否则该方法不会被触发。
例如,以下代码来自Google Cloud Print JavaScript界面,用于来自网页浏览页面的调用:
final class PrintDialogJavaScriptInterface {
@JavascriptInterface
public String toString() { return JS_INTERFACE; }
@JavascriptInterface
public String getType() {
return cloudPrintIntent.getType();
}
@JavascriptInterface
public String getTitle() {
return cloudPrintIntent.getExtras().getString("title");
}
@JavascriptInterface
public String getContent() {
try {
ContentResolver contentResolver = getActivity().getContentResolver();
InputStream is = contentResolver.openInputStream(cloudPrintIntent.getData());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[4096];
int n = is.read(buffer);
while (n >= 0) {
baos.write(buffer, 0, n);
n = is.read(buffer);
}
is.close();
baos.flush();
return Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
@JavascriptInterface
public String getEncoding() {
return CONTENT_TRANSFER_ENCODING;
}
@JavascriptInterface
public void onPostMessage(String message) {
if (message.startsWith(CLOSE_POST_MESSAGE_NAME)) {
finish();
}
}
}