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

2023-05-10 19:10:14 浏览数 (1)

首先, 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 ,那么这将是一个非常有用的功能,具体可以参考这个链接。

到此结束,再会。

0 人点赞