Search…

WebView trong Android - Phần 2

Nguyễn NghĩaNguyễn Nghĩa
11/11/20204 min read
Xử lý event trong WebView, các hạn chế của WebView và sử dụng WebView hiệu quả trong Android.

1 số hạn chế ở khi sử dụng WebView

Khai báo quyền truy cập internet trong file AndroidManifest.xml.

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
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 = "https://eitguide.net/";
    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ạy đoạn code trên thì không thấy xuất hiện vấn đề, tuy nhiên khi nhấn vào 1 đường dẫn trên web được nạp bởi WebView thì trang web này được mở bởi trình duyệt web mặc định trên Android chứ không phải là WebView. Điều này không là điều không mong đợi, tất cả sự kiện nên xử lý với WebView chứ không phải là sử dụng trình duyệt web mặc định.

Để khắc phục điều này có thể sử dụng WebViewClient.

Khắc phục vấn đề với setWebViewClient

Để mở đường dẫn mới với WebView thay vì trình duyệt web mặc định trong Android, thêm vào đoạn code sau:

webView.setWebViewClient(new WebViewClient());

Phương thức này chỉ định rằng mọi đường dẫn nhấn vào sẽ được tải lên và hiển thị trang web bởi WebView chứ không sử dụng 1 trình duyệt web 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, cần 1 số event để có thể xử lý WebView 1 cách linh hoạt, ví dụ như các event liên quan đến tải trang started, visible, error, finished.

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() thường dùng:

onPageStart

onPageStart là phương thức được gọi ngay sau khi gọi phương thức loadUrl() của WebView, thường sử dụng cho animation để làm tăng trải nghiệm người dùng.

onPageCommitVisible

onPageCommitVisible là phương thức được gọi khi WebView bắt đầu hiển thị trang web, thường sử dụng để kết thúc animation.

onPageFinished

onPageFinished là phương thức được gọi khi WebView đã hiển thị toàn bộ trang web, tải trang thành công.

onReceivedError

onReceivedError là phương thức đượ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 tải lại trang hay xử lý UI (xử lý để che hình mặc định khi WebView gặp lỗi).

Ngoài setWebViewClient, có thể tạo 1 lớp riêng và override lại các phương thức callback vừa trên như dưới đây:

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);
    }
}

setWebViewClient như sau:

webView.setWebViewClient(new MyWebViewClient());

Ngoài những phương thức callback thường sử dụng, có 1 số phương thức callback nên biết.

@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: ");
}

WebView Back Stack

1 vấn đề của WebView hay gặp đó là vấn đề về Back Stack:

  • Khi mở 1 đường dẫn thì được thêm vào Back Stack của WebView.
  • Nhưng khi nhấn trở lại thì gặp vấn đề WebView không trở lại trang trước đó.

Để xử lý trường hợp nàycần override lại phương thức onBackPress() như dưới đây:

@Override
public void onBackPressed() {
    if (webView.canGoBack()) {
        webView.goBack();
    } else {
        super.onBackPressed();
    }
}

Bài chung series

IO Stream

IO Stream Co., Ltd

developer@iostream.co
383/1 Quang Trung, ward 10, Go Vap district, Ho Chi Minh city
Business license number: 0311563559 issued by the Department of Planning and Investment of Ho Chi Minh City on February 23, 2012

©IO Stream, 2013 - 2025