您的位置:首页 > 移动开发 > Android开发

JS & JAVA(Android) 的互相调用(简介)

2017-07-06 15:58 369 查看

首先, JAVA 代码调用JS :

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 去执行, 代码如下:

//注意,这个已经在项目中被我注释掉了,因为我们有更好的解决办法
mWebView.loadUrl("javascript:changeColor()");


在android 4.4 之后我们可以使用最新的办法,这个也是用于如果js代码有返回值的话我们可以使用String来接收;

mWebView.evaluateJavascript("javascript:changeColor('hello')", new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
Log.e("chason",value);
}
});


当然, Js代码也不可少:

<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代码,那么我们肯定要有一个方法,如下定义:

@JavascriptInterface
public String  onSumResult(int number ){
Log.e("chason","js 调用 java"+number);

return "chason" ;
}


以上这个方法, 一定是要在你刚才addJavascriptInterface 方法中第一个参数类中的方法, 并且要添加 @JavascriptInterface 注解,用于表明这是一个供JS调用的方法;

接下来就是在JS代码中去调用java代码,代码如下:

<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的点击事件, 这代表着 如果点击了就执行这个方法,那么这个方法是啥呢,别着急, 我们马上说:

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方法获取返回值

自定义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方法操作

mWebView.post(new Runnable() {
@Override
public void run() {
mWebView.loadUrl(...);

}
});


Tips: 对于字符串形式的参数,一定要记住使用单引号 ’ 将其包裹,否则 JavaScript(可能)会无法解析这个字符串,提示未定义。

三、调试

Chrome 远程调试

如果你使用的是 Android 4.4 及其以上版本的 WebView ,那么这将是一个非常有用的功能,具体可以参考这个链接。

到此结束,再会。

end…..

哦还有Sample 地址 : https://github.com/ichason/JS-JAVA-Android-Link-to-each-other 欢迎诸君Start
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: