package com.loaderman.webviewdemo; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.webkit.JavascriptInterface; import android.webkit.WebChromeClient; import android.webkit.WebSettings; import android.webkit.WebView; import android.widget.Toast; public class MainActivity extends AppCompatActivity { private WebView mWebView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mWebView = (WebView) findViewById(R.id.wv_test); WebSettings settings = mWebView.getSettings(); settings.setJavaScriptEnabled(true);//开启js mWebView.loadUrl("file:///android_asset/demo.html");//加载本地网页 mWebView.setWebChromeClient(new WebChromeClient());//此行代码可以保证js的alert弹窗正常弹出 //核心方法, 用于处理js被执行后的回调 mWebView.addJavascriptInterface(new JsCallback() { @JavascriptInterface//注意:此处一定要加该注解,否则在4.1+系统上运行失败 @Override public void onJsCallback() { Toast.makeText(MainActivity.this, "js调用Android啦", Toast.LENGTH_SHORT).show(); } }, "demo");//参1是回调接口的实现;参2是js回调对象的名称 } //定义回调接口 public interface JsCallback { void onJsCallback(); } // android调用js public void androidCallJs(View view) { mWebView.loadUrl("javascript:wave()"); } }
在main/assets下新建demo.html
<head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> </head> <script language="javascript"> /* This function is invoked by the activity */ function wave() { alert("Android调用Js啦"); } </script> <body>a <!-- Js调用Android代码 --> <a onClick="window.demo.onJsCallback()"> <div style="80px; margin:0px auto; padding:10px; text-align:center; border:2px solid #202020;"> <img id="droid" src="android_normal.png"/><br> Click me! </div> </a> </body>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.loaderman.webviewdemo.MainActivity"> <Button android:text="android调用js" android:layout_width="match_parent" android:onClick="androidCallJs" android:layout_height="wrap_content"/> <WebView android:id="@+id/wv_test" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
添加网络权限:
<uses-permission android:name="android.permission.INTERNET"/>
效果实现:
注意: js回调的方法的书写格式: onClick="window.demo.onJsCallback() 格式是: window.js回调对象的名称(要和java代码中设置的一致).回调方法名称(要和java代码中设置的一致)
Js调用Android的方式具有版本兼容问题. 经测试, 在2.2, 4.0+ 系统上运行稳定, 可以正常调用, 但是在2.3系统上运行时出现崩溃.原因是底层进行JNI调用时,把一个Java中的String对象当数组来访问了,最终导致虚拟机崩溃. 基本算是一个比较严重的BUG,没办法解决,所以如果说用WebView组件想在js和java之间相互调用的话就没办法适应所有机型.