Giới thiệu
Tiếp nối bài viết trước về cách sử dụng master WebView trong Android. Hôm nay mình sẽ phân tích một số hạn chế ở bài viết trước và chỉ ra các event mà chúng ta thường xuyên sử dụng khi làm việc với WebView trong Android để chúng ta có thể Handle tất cả các trường hợp với WebView một cách hiệu quả nhất.
Một số hạn chế ở khi sử dụng WebView trong bài viết trước
Trong bài trước chúng ta load trang web vào webview như sau:
Khai báo quyền truy cập INTERNET trong file AndroidManifest.xml
1 2 |
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> |
Và load với đường dẫn website. Ở đây mình sử dụng website của mình luôn.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
package com.eitguide.demowebview; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.webkit.WebView; public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; private static final String EITGUIDE_URL = "http://eitguide.com/"; private WebView webView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); webView = (WebView)findViewById(R.id.webview); webView.getSettings().setJavaScriptEnabled(true); webView.loadUrl(EITGUIDE_URL); } } |
Khi chúng ta chạy đoạn code trên kia lên thì chúng ta không thấy vấn đề gì xảy ra. Tuy nhiên khi bạn click vào 1 link trên website render bởi webview thì sẽ được mở bởi browser mặc định trên máy Android chứ không phải là WebView. Điều này chúng ta không cần đến, vì chúng ta sẽ phải handle tất cả mà chúng ta sẽ làm với webview chứ không phải là sử dụng trình duyệt mặc định. Để khắc phục điều đó chúng ta phải sử dụng WebViewClient của chúng ta.
Khắc phục vấn đề với setWebViewClient
Để khắc phục lỗi mở đường dẫn với trình duyệt với browser mặc định của Android khi chúng ta click vào đường link trên WebView chúng ta cần sử dụng phương thức.
1 |
webView.setWebViewClient(new WebViewClient()); |
Phương thức này sẽ chỉ định rằng mọi link mà chúng ta click vào sẽ được load và render bởi WebView chứ không sử dụng một browser nào khác.
Các phương thức callback thường dùng khi thao tác với WebView
Trong khi sử dụng WebView chúng ta cần một số event để có thể handle được WebView một cách link hoạt nhất ví dụ như các event liên quan đến load trang started, visible, error, finished.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
webView.setWebViewClient(new WebViewClient(){ @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { super.onPageStarted(view, url, favicon); } @Override public void onPageCommitVisible(WebView view, String url) { super.onPageCommitVisible(view, url); } @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); } @Override public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) { super.onReceivedError(view, request, error); } @Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { super.onReceivedError(view, errorCode, description, failingUrl); } }); |
Có 5 phương thức callback mà chúng ta thường dùng
onPageStart
Phương thức này được call ngày sau khi chúng ta gọi phương thức loadUrl của WebView. Thường sử dụng cho việc show animation loading tăng trải nghiệm người dùng.
onPageCommitVisible
Phương thức này được gọi khi WebView bắt đầu render và visible. Thường sử dụng để kết thúc animation.
onPageFinished
Phương thức này được gọin khi mà WebView đã render toàn bộ trang, load trang thành công.
onReceivedError
Phương thức này được gọi khi có lỗi xảy ra ví dụ như không có mạng, đường dẫn không đúng… Thường dùng cho việc load lại trang hay xử lý UI (Xử lý để che hình mặc định khi webview bị lỗi)
Ngoài việc setWebViewClient như trên chúng ta có thể tạo một class riêng và override lại các phương thức callback vừa nêu ở trên như dưới đây
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
public class MyWebViewClient extends WebViewClient{ @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { super.onPageStarted(view, url, favicon); } @Override public void onPageCommitVisible(WebView view, String url) { super.onPageCommitVisible(view, url); } @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); } @Override public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) { super.onReceivedError(view, request, error); } @Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { super.onReceivedError(view, errorCode, description, failingUrl); } } |
Và setWebViewClient như sau
1 |
webView.setWebViewClient(new MyWebViewClient()); |
Ngoài những phương thức callback thường sử dụng thì có một số phương thức callback chúng ta cũng nên biết.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
@Override public void onFormResubmission(WebView view, Message dontResend, Message resend) { super.onFormResubmission(view, dontResend, resend); Log.e(TAG, "onFormResubmission: " ); } @Override public void onLoadResource(WebView view, String url) { super.onLoadResource(view, url); Log.e(TAG, "onLoadResource: " ); } @Override public void onReceivedClientCertRequest(WebView view, ClientCertRequest request) { super.onReceivedClientCertRequest(view, request); Log.e(TAG, "onReceivedClientCertRequest: "); } @Override public void onReceivedLoginRequest(WebView view, String realm, String account, String args) { super.onReceivedLoginRequest(view, realm, account, args); Log.e(TAG, "onReceivedLoginRequest: "); } @Override public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm) { super.onReceivedHttpAuthRequest(view, handler, host, realm); Log.e(TAG, "onReceivedHttpAuthRequest: " ); } @Override public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) { super.onReceivedHttpError(view, request, errorResponse); Log.e(TAG, "onReceivedHttpError: " ); } @Override public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { super.onReceivedSslError(view, handler, error); Log.e(TAG, "onReceivedSslError: "); } @Override public void onScaleChanged(WebView view, float oldScale, float newScale) { super.onScaleChanged(view, oldScale, newScale); Log.e(TAG, "onScaleChanged: " ); } @Override public void onUnhandledKeyEvent(WebView view, KeyEvent event) { super.onUnhandledKeyEvent(view, event); Log.e(TAG, "onUnhandledKeyEvent: "); } @Override public void onTooManyRedirects(WebView view, Message cancelMsg, Message continueMsg) { super.onTooManyRedirects(view, cancelMsg, continueMsg); Log.e(TAG, "onTooManyRedirects: "); } |
BackStack WebView
Tiếp đến một vấn đề của WebView nữa mà chúng ta hay gặp đó là vấn đề về BackStack. Khi chúng ta mở một đường dẫn thì nó sẽ được thêm vào backstack của WebView. Nhưng khi chúng ta nhấn Back thì gặp vấn đề webview không back lại trang trước đó. Để xử lý trường hợp này chúng ta nên override lại phương thức onBackPress như dưới đây:
1 2 3 4 5 6 7 8 |
@Override public void onBackPressed() { if (webView.canGoBack()) { webView.goBack(); } else { super.onBackPressed(); } } |
Kết luận
Qua hai bài viết mình cũng đã giới thiệu cho các bạn cách sử WebView trong Android. Việc sử dụng các phương thức callback giúp chúng ta có thể handle được tất cả các trường hợp mà chúng ta sẽ làm với WebView mà người dùng sẽ không nhận ra chúng ứng dụng của chúng ta đã “nhúng” một trình duyệt vào trong app và không khác gì so với việc mở browser. Ở bài viết tiếp mình sẽ hướng dẫn các phần còn lại để chúng ta sử dụng WebView một cách master.
bạn hướng dẫn làm 1 webview như của thằng zalo lun đi bạn. thanks bạn 🙂
cảm ơn bạn bài viết rất dễ hiểu.chờ phần tiếp của bạn 🙂
Có ngay đây bạn: http://eitguide.net/master-webview-trong-android-phan-3/