首先, JAVA 代码调用JS :
代码语言:javascript复制 mWebView= (WebView) findViewById(R.id.webView);
settings = mWebView.getSettings();
settings.setJavaScriptEnabled(true);
mWebView.loadUrl("file:///android_asset/javaInterface.html");
//以上我都不说了, 相信诸位可以理解, 下面的函数是添加js接口,第一个参数是指的你这个WebView绑定的是哪一个类, 如果你把鼠标放上去则可以看到这个方法的第一个参数的父类是Object; 第二个是暴露名称, 主要是用于找到该类, 也可以看做成这个类的一个实例(自己的理解)
mWebView.addJavascriptInterface(MainActivity.this,"javaInterface");
说到调用方法, 那么我们首先得有一个方法可以让我们去调用,在Android 4.4 之前我们可以使用 loadurl 去执行, 代码如下:
代码语言:javascript复制//注意,这个已经在项目中被我注释掉了,因为我们有更好的解决办法
mWebView.loadUrl("javascript:changeColor()");
在android 4.4 之后我们可以使用最新的办法,这个也是用于如果js代码有返回值的话我们可以使用String来接收;
代码语言:javascript复制 mWebView.evaluateJavascript("javascript:changeColor('hello')", new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
Log.e("chason",value);
}
});
当然, Js代码也不可少:
代码语言:javascript复制<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Untitled Document</title>
</head>
<div id="div" style="width:100px; height:100px; background-color:#099;" onclick="window.javaInterface.onSumResult(1)">
</div>
<body>
</body>
<script type="text/javascript">
function changeColor(value){
document.getElementById("div").style.backgroundColor='red';
alert("My First JavaScript");
return "无敌棒棒糖:" value javaInterface.onSumResult(1);;
}
</script>
</html>
需要注意的是, 在Js中 function 是声明方法的关键字, 这个如果你懂js的话我就不再多话, 如果,你不懂,那么打开网页戴上耳机关掉王者荣耀,沉浸在学习的海洋中。
其次,就是Js调用Java代码:
首先要调用java代码,那么我们肯定要有一个方法,如下定义:
代码语言:javascript复制 @JavascriptInterface
public String onSumResult(int number ){
Log.e("chason","js 调用 java" number);
return "chason" ;
}
以上这个方法, 一定是要在你刚才addJavascriptInterface 方法中第一个参数类中的方法, 并且要添加 @JavascriptInterface 注解,用于表明这是一个供JS调用的方法;
接下来就是在JS代码中去调用java代码,代码如下:
代码语言:javascript复制<div id="div" style="width:100px; height:100px; background-color:#099;" onclick="window.javaInterface.onSumResult(1)">
</div>
<body>
</body>
<script type="text/javascript">
function changeColor(value){
document.getElementById("div").style.backgroundColor='red';
alert("My First JavaScript");
return "无敌棒棒糖:" value javaInterface.onSumResult(1);;
}
</script>
哦好吧,被你发现了,这跟上一份JS代码确实差不多, 不过我要说的可就不一样了, 首先请看 div的点击事件, 这代表着 如果点击了就执行这个方法,那么这个方法是啥呢,别着急, 我们马上说:
代码语言:javascript复制window.javaInterface.onSumResult(1);
首先不用管Window(因为我在后期测试中,不加也可以);
注意看 “javaInterface” ,这个其实是跟我们刚开始写 JAVA 调用JS 时addJavascriptInterface 时添加的一个暴露名称,ok,他现在终于派上用场了, 我说过你可以理解为一个实例, 所以我们得用它去.出来一个方法。
对的,不出你所料, onSumResult 就是我们的方法,还记得他添加的 @JavascriptInterface 注解吗? 这一定不要忘记了。
ok,当你点击的时候,就执行了java代码中的方法, 你可以去自己试试。
最后,注意事项及要点:
大家可能要问, 如果在4.4之前的话,诸多事项怎么解决呢?
一、 Android 4.4 之前 JAVA 调用J S并取到返回值
目前的解决方案是通过java反射机制 在android.webkit包中有个BrowserFrame私有类,该类中有个Native方法: public native String stringByEvaluatingJavaScriptFromString(String script) 使用步骤 1.扩展WebView添加方法,并使用反射实现。 2.将布局文件中的WebView修改为自定义的WebView 3.使用新的WebView调用方法,执行js方法获取返回值
代码语言:javascript复制自定义WebView如下
public String stringByEvaluatingJavaScriptFromString(String script) {
try {
//由webview取到webviewcore
Field field_webviewcore = WebView.class.getDeclaredField(“mWebViewCore”);
field_webviewcore.setAccessible(true);
Object obj_webviewcore = field_webviewcore.get(this);
//由webviewcore取到BrowserFrame
Field field_BrowserFrame = obj_webviewcore.getClass().getDeclaredField(“mBrowserFrame”);
field_BrowserFrame.setAccessible(true);
Object obj_frame = field_BrowserFrame.get(obj_webviewcore);
//获取BrowserFrame对象的stringByEvaluatingJavaScriptFromString方法
Method method_stringByEvaluatingJavaScriptFromString = obj_frame.getClass().getMethod(“stringByEvaluatingJavaScriptFromString”, String.class);
//执行stringByEvaluatingJavaScriptFromString方法
Object obj_value = method_stringByEvaluatingJavaScriptFromString.invoke(obj_frame, script);
//返回执行结果
return String.valueOf(obj_value);
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
二、 只能在主线程进行调用js方法操作
代码语言:javascript复制mWebView.post(new Runnable() {
@Override
public void run() {
mWebView.loadUrl(...);
}
});
Tips: 对于字符串形式的参数,一定要记住使用单引号 ’ 将其包裹,否则 JavaScript(可能)会无法解析这个字符串,提示未定义。
三、调试
Chrome 远程调试
如果你使用的是 Android 4.4 及其以上版本的 WebView ,那么这将是一个非常有用的功能,具体可以参考这个链接。
到此结束,再会。