原標題「Java I/O 流詳解」與內容不符,實際為 Android WebView 呼叫 Java 方法 以及 Java 呼叫 JavaScript 的完整雙向通訊範例。
WebView.addJavascriptInterface(Object, "interfaceName") 註入 Java 物件,JS 透過 interfaceName.method() 呼叫。WebView.loadUrl("javascript:functionName()") 在 UI 執行緒注入並執行 JS 代碼。public class JsWebDemo extends Activity {
private WebView wView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
wView = findViewById(R.id.wv1);
WebSettings settings = wView.getSettings();
settings.setJavaScriptEnabled(true); // 必須啟用 JS
// 單一物件註入(僅暴露特定方法)
wView.addJavascriptInterface(new ProxyBridge(), "AliansBridge");
// 或註入整個 Activity(暴露所有 public 方法,風險較高)
// wView.addJavascriptInterface(this, "AliansBridge");
wView.loadUrl("file:///android_asset/index.html");
}
private class ProxyBridge {
@JavascriptInterface // API 17+ 必須加註解才允許被 JS 呼叫
public int one() { return 1; }
}
}
<html>
<script>
function callJava() {
// 呼叫 Java 方法並取得回傳值
var result = AliansBridge.one();
document.getElementById('output').innerHTML = result;
}
</script>
<body>
<input type="button" value="呼叫 Java" onclick="callJava()" />
<div id="output">Test page</div>
</body>
</html>
// 必須在 UI 執行緒執行 loadUrl
mHandler.post(() -> mWebView.loadUrl("javascript:wave()"));
// 完整範例:JS 呼叫 Java,Java 再回呼 JS
mWebView.addJavascriptInterface(new Object() {
@JavascriptInterface
public void clickOnAndroid() {
mHandler.post(() -> mWebView.loadUrl("javascript:wave()"));
}
}, "demo");
mWebView.setWebChromeClient(new WebChromeClient() {
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
// 自訂對話框或直接確認
result.confirm();
return true; // 表示已處理
}
});
-keepclassmembers class * { @android.webkit.JavascriptInterface public *; }。loadUrl("javascript:...") 必須在主執行緒;JS 呼叫 Java 時運行於 WebView 核心執行緒(非 UI 執行緒),若需更新 UI 必須切回主執行緒。