Android原生方法和Web JS互相调用
准备工作
- 新建一个Android项目
- 准备一个html文件,为了简化,直接放到项目的assets目录下调用
JS调用Android原生方法
在Android项目中
配置WebView,WebView的配置中必须启用JavaScript,添加JavaScript的入口接口,方法如下:
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new H5Interface(MainActivity.this, webView), "h5_android");
在html文件中
添加JavaScript代码 在JavaScript中调用Android本地接口的格式是“本地JavaScript接口名称.接口方法名称”,接口名称是Android WebView调用addJavascriptInterface方法时的第二个参数,方法如下:
h5_android.login(platform, extInfo);
Android原生方法调用JS
在html中
添加JavaScript代码,编写一个JavaScript方法
在Android项目中
在打开当前页面的WebView对象,调用loadUrl方法执行JavaScript方法,URL格式为"javascript:JavaScript方法名()",但必须注意的是,如果JavaScript方法的参数是字符串,必须添加单引号将内容括起来,否则会当做一个对象,方法如下:
···
mmWebView.loadUrl(String.format("javascript:onLoginResult('%s')", "登录取消"));
···
注意:调用loadUrl的WebView对象必须是打开当前页面的WebView
本地JavaScript调用入口类代码如下:
class H5Interface {
private Activity mmActivity;
private WebView mmWebView;
public H5Interface(Activity activity, WebView webView) {
this.mmActivity = activity;
this.mmWebView = webView;
}
@JavascriptInterface
public void login(String platform, String extInfo) {
mmActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
WAUserProxy.loginUI(mmActivity, false, new WACallback<WALoginResult>() {
@Override
public void onSuccess(int i, String s, WALoginResult waLoginResult) {
mmWebView.loadUrl(String.format("javascript:onLoginResult('%s')", new Gson().toJson(waLoginResult)));
}
@Override
public void onCancel() {
mmWebView.loadUrl(String.format("javascript:onLoginResult('%s')", "登录取消"));
}
@Override
public void onError(int i, String s, WALoginResult waLoginResult, Throwable throwable) {
mmWebView.loadUrl(String.format("javascript:onLoginResult('登录失败:\ncode: %d\n message: %s')", i, s));
}
});
}
});
}
}
上面代码中可以看到,H5Interface类中有一个login成员方法,这个方法就是在html页面的JavaScript中调用的。
注意:开放给JavaScript调用的方法必须添加@JavascriptInterface注解,在 JELLY_BEAN/API 16/4.1开始必须添加,否则JavaScript无法调用到这个接口
html代码如下
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function login(platform, extInfo) {
h5_android.login(platform, extInfo);
}
function onLoginResult(result) {
document.getElementById("messageArea").textContent = result
}
</script>
</head>
<body>
<h1 align="center">Android与JS互调示例</h1>
<h2>JS调用Android原生功能</h2>
<input type="button"
style="width:100%; font-size: 25px"
value="登录"
onClick="login('', '')"/>
<h2>Android调用JS</h2>
<div style="font-size: 25px">登录结果:</div>
<div style="width: 100%">
<textarea id="messageArea" rows="10" style="width: 100%; font-size: 25px"></textarea>
</div>
</body>
</html>
特别注意:JS执行的代码不在Android的UI线程中,是在WebView Core的线程中,所以JS调用Android的接口中,需要添加到Activity.runOnUiThread中