Trong phần 1 và phần 2 của chuyên mục thì chúng tôi đã giới thiệu cách load một trang web tĩnh được lưu trực tiếp trong Assets đổ vào WebView. Hôm nay, chúng tôi sẽ tiếp tục trình bày phần cuối cùng, gọi hàm Java từ Javascript trong WebView.
Mục đích chính của việc này là giúp các bạn làm một Help Activity để chứa phần Trợ giúp trong ứng dụng của các bạn. Thực chất bạn vẫn có thể dùng các Views để bố trí chúng, nhưng đối với phần có nội dung phức tạp thì việc làm một trang HTML sẽ dễ dàng hơn rất nhiều. Bạn cũng có thể thiết kế toàn bộ giao diện ứng dụng bằng Web rồi bắt sự kiện onclick trên các HTML elements gọi các hàm trong Java, chẳng hạn như tôi sẽ trình bày dưới đây.
Đầu tiên tôi có 1 trang index.html đơn giản như sau:
1 2 3 4 5 6 7 8 9 10 11 12 |
<!DOCTYPE HTML> <html> <head><title>Hello EITGUIDE</title></head> <body style="text-align: center"> <button style="background: transparent; border: 1px solid black; color: black; margin: auto; top: 20px;">SHOW TOAST FROM HTML</button> <script> var button = document.getElementsByTagName("button")[0]; function showToast(toast) { } // Empty function button.onclick = function() { showToast("Hello from EITGUIDE"); } </script> </body> </html> |
Bây giờ, tôi sẽ cho gọi Toast qua button đó. Mà bạn biết rồi, Toast.makeText(…) trong Java chứ không phải Javascript. Do đó, tôi sẽ phải kết nối giữa phần JS trong Webview và Java trong phần logic của tôi qua một Javascript Interface. Giả sử Activity của tôi có code sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
class MainActivity extends Activity { WebView mWebView; void onCreate(Bundle b) { super.onCreate(b); setContentView(R.id.activity_main); mWebView = (WebView) findViewById(R.id.webview); mWebView.loadUrl("file:///android_asset/index.html"); } class JsInterface extends Object { } } |
Mặc định thì toàn bộ phần scripts sẽ bị tắt khi WebView load một Url, bất kể đó là Url từ internet hay assets. Do đó bạn phải bật JS lên:
1 2 |
WebSettings webSettings = mWebView.getSettings(); webSettings.setJavaScriptEnabled(true); |
Tiếp theo là bạn tạo một JsInterface (tôi đã tạo trong phần trên). Trong đó, tôi định nghĩa hàm showToast như sau:
1 2 3 4 5 6 |
class JsInterface extends Object { @JavascriptInterface public void showToast(String toast) { Toast.makeText(MainActivity.this, toast, Toast.LENGTH_SHORT).show(); } } |
Lưu ý là bạn phải có JavascriptInterface annotation thì mới gọi được hàm. Còn không thì mọi công sức của bạn sẽ “chỉ để ngắm”. Bây giờ ta sẽ liên kết JsInterface và mWebView qua một interface. Thực tế thì tên gì cũng được, nhưng tốt hơn bạn đặt tên là “Android” để cho dễ bảo trì:
1 |
mWebView.addJavascriptInterface(new JsInterface(), "Android"); |
Cuối cùng, tôi quay lại phần JS trong HTML và code lại hàm showToast(toast) như sau. Lưu ý là String interface phải giống nhau:
1 2 3 |
function showToast(toast) { Android.showToast(toast); // <- Chữ "Android" là từ tham số thứ hai trong mWebView.addJavascriptInterface(new JsInterface(), "Android") } |
Xong xuôi, và bây giờ bạn có thể cho showToast, với sự kiện onclick nằm trong HTML button chứ không còn là Button widget của Android nữa. Tuy nhiên, hãy cẩn trọng, chỉ nên cho phép và gọi hàm Java/Javascript đối với trang web bạn tự tạo và lưu trong assets, không nên làm thao tác này đối với 1 trang web trên internet vì lí do bảo mật. Chúc các bạn thành công.
Còn kích hoạt event từ java sang javascript nữa nhé. Bạn giới thiệu luôn cho đủ bộ.
Bạn dùng hàm WebView#loadUrl(String url) để thực hiện. Bản thân mình không thích, nếu nói tránh chữ “ghét”, việc này vì lí do bảo mật. Thứ nhất: Mình chỉ khuyến nghị các bạn sử dụng WebView với nội dung tĩnh trong Assets hoặc trỏ tới trang của bạn để làm phần Trợ giúp cho ứng dụng. Nếu bạn có ý định load JS từ Java thì bạn nên cân nhắc làm luôn các events đó trong JS luôn, hoặc là làm APIs trên server, còn dưới Android app, bạn làm luôn một activity hay fragment rồi gửi thông tin lên.
Làm cái loading quay quay khi click vào 1 link trên webview luôn bạn ơi, hiện tại khi click vào nó cứ đơ ra đợi webview load xong mới hiển thị nội dung
Bạn dùng WebView#setWebViewClient(WebViewClient) với các hàm trong WebViewClient được giải thích ở đây: https://developer.android.com/reference/android/webkit/WebViewClient.html
Bạn có thể đọc thêm ở đây: https://stackoverflow.com/questions/16849347/adding-a-progress-dialog-in-a-webview