Android WebView中从Java调用JavaScript函数问题
解决WebView中Java调用Google Charts JS函数无效的问题
你遇到的核心问题是调用时机不匹配:浏览器里你是等页面完全加载、Google Charts脚本也加载完成后才手动调用draw(),但WebView中你刚执行loadUrl就立刻调用evaluateJavascript,这时候不仅Google Charts的脚本可能还没加载,甚至页面DOM都未必完全就绪,自然不会有效果。
下面是两种可靠的解决思路,推荐第一种:
方法一:让JS主动通知Java准备就绪(最稳妥)
通过JavascriptInterface让JS在Google Charts真正加载完成后,通知Android端再调用draw()方法,完美匹配异步加载的时序。
修改后的Java代码
webView.getSettings().setJavaScriptEnabled(true); // 允许JS调用Java的接口 webView.addJavascriptInterface(new ChartsReadyInterface(), "AndroidBridge"); webView.setWebViewClient(new WebViewClient() { @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); // 这里只是页面DOM加载完成,Google Charts还在异步加载,所以不用急着调用JS } }); webView.loadUrl("file:///android_asset/html/chart.html"); // 定义供JS调用的Java接口 class ChartsReadyInterface { @JavascriptInterface // 必须加这个注解,Android 4.2+强制要求 public void onChartsLoaded() { // 收到JS的就绪通知,在主线程调用draw方法 webView.post(() -> { webView.evaluateJavascript("draw();", null); }); } }
修改后的HTML/JS代码
<html> <head> Hello World! </head> <body> <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script> <script type="text/javascript"> // 先加载Google Charts核心包 google.charts.load('current', {'packages':['corechart']}); // 当Charts加载完成后,通知Android端 google.charts.setOnLoadCallback(() => { // 检查AndroidBridge是否存在(避免浏览器测试时报错) if (typeof AndroidBridge !== 'undefined') { AndroidBridge.onChartsLoaded(); } }); function draw(){ drawChart(); } function drawChart() { // 创建数据表 var data = new google.visualization.DataTable(); data.addColumn('string', 'Topping'); data.addColumn('number', 'Slices'); data.addRows([ ['Mushrooms', 3], ['Onions', 1], ['Olives', 1], ['Zucchini', 1], ['Pepperoni', 2] ]); // 设置图表选项 var options = {'title':'How Much Pizza I Ate Last Night', 'width':400, 'height':300}; // 实例化并绘制图表 var chart = new google.visualization.PieChart(document.getElementById('chart_div')); chart.draw(data, options); } </script> <div id="chart_div"></div> </body> </html>
方法二:延迟调用(简单但不推荐)
如果不想用接口通信,可以在onPageFinished里延迟一段时间再调用evaluateJavascript,但这种方法不可靠——不同设备的网络速度、加载时间不一样,延迟设置短了可能还是没加载完,设置长了影响体验:
@Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); // 延迟2秒调用,仅作临时测试用 new Handler(Looper.getMainLooper()).postDelayed(() -> { webView.evaluateJavascript("draw();", null); }, 2000); }
额外注意事项
- Android 9+需要确保允许加载网络资源:如果你的Manifest里没有设置
android:usesCleartextTraffic="true",要确认Google Charts的CDN是HTTPS(你用的https://www.gstatic.com已经满足,所以没问题)。 - 不要忘记
@JavascriptInterface注解,否则Android 4.2及以上版本会禁止JS调用Java方法,这是安全机制要求。
内容的提问来源于stack exchange,提问作者Dirk
相关产品推荐
相关产品推荐

