本篇功能主要介绍Android 中 Native层与Html层的交互
前提:
mWebView.getSettings().setJavaScriptEnabled(true); // 设置支持javascript脚本
mWebView.loadUrl("file:///android_asset/test.html"); // 本地assets下面测试页面
1. native层调用 html层中js方法(可携带参数)
1.1 java调用js方法无返回值
java 通过webview 的loadUrl调用 js方法无法接收返回值,调用如下:
java code:
mWebView.loadUrl("javascript:CallJsMethod()"); // CalljsMethod() 为js中声明的方法(无参)
mWebView.loadUrl("javascript:CallJsMethodParams("+"calljsMethod"+")"); // 携参调用js方法
html code:
function CallJsMethod() {
alert("我是js方法我被javca层调用了= 0 =");
}
function CallJsMethodParams(param) {
alert("我是js方法我被java调用接收参数为【" + param+ "]");
}
1.2 java调用js方法接收其返回值
现在需求是 通过java层调用js中的方法并接收js方法返回的数据,实现方式有二种,
方式1: java层调用js方法,在该js方法内携参回调java层指定的方法将参数传递过去
java code:
mWebView.loadUrl("javascript:javaCallJSRretunStrMethod()");
/**
* js 回调java方法 有参数
*/
@JavascriptInterface
public void CallBackJavaMethodParam(String str){
Toast.makeText(WebViewActivity.this, "java调用js方法的返回数据为【" + str + "】", Toast.LENGTH_SHORT).show();
}
html code:
function javaCallJSRretunStrMethod() {
window.jscalljava.CallBackJavaMethodParam("JS返回数据");
alert("JS返回数据");
}
方式2:使用webview. evaluateJavascript()方法异步执行javascript方法并获取返回值
java code:
String script=String.format("javascript: CallJSRretunStrMethod()");
mWebView.evaluateJavascript(script, new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
Log.d(TAG, "value=" + value);
}});
html code:
<span style="font-family:FangSong_GB2312;font-size:18px;">function CallJSRretunStrMethod() {
return "呵呵呵哒"; }</span>
有没有发现通过java层调用js方法alert却不起作用????
解决办法:设置webview 的 setWebChromeClient
mWebView.setWebChromeClient(new WebChromeClient() {
@Override
public boolean onJsAlert(WebView view, String url, String message, final android.webkit.JsResult result)
{
new AlertDialog.Builder(WebViewActivity.this)
.setTitle("dialog")
.setMessage(message)
.setPositiveButton(android.R.string.ok, new AlertDialog.OnClickListener()
{
public void onClick(DialogInterface dialog, int which){
result.confirm();
}
})
.setCancelable(false)
.create()
.show();
return true;
};
});
2.js层调用native层的方法(可携带参数)
js调用native方法需要设置 addJavascriptInterface (arg1,arg2);
addJavascriptInterface方法有两个参数,第一个参数就是我们一般会实现一个自己的类,类里面提供我们要提供给javascript访问的方法;第二个参数是访问我们在obj中声明的方法时候所用到的js对象.
mWebView.addJavascriptInterface(new JSCallJava(), "jscalljava");
class JSCallJava {
/**
* js 调用java方法 无参 无返回值
*/
@JavascriptInterface
public void CallJavaMethod() {
Toast.makeText(WebViewActivity.this, "我是java方法我被js调用了",Toast.LENGTH_SHORT).show();
}
/**
* js调用java方法 有参 并且js接收其返回值
*/
@JavascriptInterface
public String CallJavaMethodParam(final String param) {
Toast.makeText(WebViewActivity.this,"我是java方法我被js调用了接受参数为 【" + param + "]", Toast.LENGTH_SHORT).show();
return "我是java层方法我被js调用了接受参数为 【" + param + "]";
}
/**
* js 回调java方法 有参数
*/
@JavascriptInterface
public void CallBackJavaMethodParam(String str){
Toast.makeText(WebViewActivity.this, "java调用js方法的返回数据为【" + str + "】", Toast.LENGTH_SHORT).show();
}
}
@JavascriptInterface之后就必须要考虑混淆时候的问题,如果混淆的时候把@JavascriptInterface搞丢了你的程序就无法调用了。
其实很简单,你只需要在混淆里面加上:
-keepattributes Annotation
-keepattributes JavascriptInterface
然后再混淆就没问题了!