Android通过WebView
组件加载HTML页面,利用JavaScript接口或evaluateJavascript
方法实现原生与JS的双向通信。
步骤 | Android端操作 | JS端操作 | 数据流向 |
---|---|---|---|
1 | 创建WebView并启用JS | 无 | |
2 | 添加JS接口(可选) | 定义JS函数 | |
3 | 调用JS方法 | 接收参数 | |
4 | 处理JS回调 | 调用Android方法 |
Android端配置
// 初始化WebView WebView webView = findViewById(R.id.webView); webView.getSettings().setJavaScriptEnabled(true); // 启用JS // 方式1:通过evaluateJavascript直接调用 webView.evaluateJavascript("javascript: receiveData('Hello from Android')", null); // 方式2:添加JS接口 webView.addJavascriptInterface(new Object() { @JavascriptInterface public void sendMessage(String data) { Log.d("JS->Android", data); } }, "Android");
JS端接收
<script> // 方式1:直接定义函数 function receiveData(data) { console.log("Received from Android: " + data); // 调用Android方法返回数据 Android.sendMessage("Processed: " + data); } </script>
数据格式:建议使用JSON字符串传递复杂对象
String json = new Gson().toJson(myObject); webView.evaluateJavascript("handleData(" + json + ")", null);
安全限制:
addJavascriptInterface
需标注@JavascriptInterface
evaluateJavascript
线程处理:JS执行在WebView主线程,耗时操作需开异步线程
Android端触发流程
// 准备数据 Map<String, Object> params = new HashMap<>(); params.put("type", "user"); params.put("name", "John Doe"); String json = new Gson().toJson(params); // 调用JS方法 webView.evaluateJavascript("processUserData(" + json + ")", new ValueCallback<String>() { @Override public void onReceiveValue(String result) { // 处理JS返回结果 Log.d("JS Response", result); } });
JS端处理逻辑
<script> function processUserData(data) { const obj = JSON.parse(data); console.log("User Type: " + obj.type); console.log("User Name: " + obj.name); // 返回处理结果 return "Processed user: " + obj.name; } </script>
A:通过addJavascriptInterface
注入对象,JS直接调用接口方法:
// Android端注入接口 webView.addJavascriptInterface(new Object() { @JavascriptInterface public void logMessage(String msg) { Log.d("JS-LOG", msg); } }, "NativeLogger"); // JS端调用 <script> NativeLogger.logMessage("This is a log message"); </script>
A:优化方案:
setTimeout
分段处理数据// Android端发送压缩数据 String compressed = compressData(json); // 自定义压缩方法 webView.evaluateJavascript("receiveCompressedData('" + compressed + "')", null);