2.攔截WebView事件

weixin_34402408發表於2018-11-06

2.1 問題

應用程式使用WebView顯示內容,但在使用者點選頁面中的連結時還需要監聽和響應。

2.2 解決方案

(API Level 1)
實現一個WebViewClient並把它關聯到WebView上。WebViewClient和WebChromeClient是兩個WebKit類,它們可以讓應用程式獲得WebView的事件回撥並且可以自定義WebView的行為。預設情況下,在沒有指定WebViewClient時,WebView會將一個URL傳遞給ActivityManager處理。而ActivityManager通常會在瀏覽器應用程式中開啟使用者點選的連結,而不是當前的WebView中。

2.3 實現機制

在程式碼清單中,可建立一個含有WebView的Activity,該WebView將處理它自己的URL載入。

帶有一個WebView的Activity的Activity,該WebView會處理URL

public class MyActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        WebView webview = new WebView(this);
        webview.getSettings().setJavaScriptEnabled(true);
        //新增一個客戶端到檢視上
        webview.loadUrl("http://www.baidu.com/");

        setContentView(webview);
    }
}

在本例中,只是簡單地為WebView提供了一個單純功能的WebViewClient,它可以讓WebView自己處理所有的URL請求,而不是將這些請求傳遞給ActivityManager,因此點選一個連結會在原來的檢視中載入請求的頁面,這是因為shouldOverrideUrlLoading()的預設實現會簡單地返回false,告訴客戶端將URL傳遞給WebView而不是應用程式。
在下一個示例中,我們將利用WebViewClient.shouldOverrideUrlLoading()回撥來攔截和監控使用者的Activity(參見以下程式碼清單)。
攔截WebView URL的Activity

public class MyActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        WebView webview = new WebView(this);
        webview.getSettings().setJavaScriptEnabled(true);
        //新增一個客戶端到檢視上
        webView.setWebViewClient(mClient);
        webview.loadUrl("http://www.baidu.com/");

        setContentView(webview);
    }
    
    private WebViewClient mClient = new WebViewClient(){
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            Uri request = Uri.parse(url);
            if (TextUtils.equals(request.getAuthority(),"www.baidu.com")){
                //允許載入
                return false;
            }
            Toast.makeText(MyActivity.this,"Sorry,buddy",Toast.LENGTH_SHORT).show();
            return true;
        }
    };
}

在本例中,shouldOverrideUrlLoading()會根據傳入的URL決定使用是否要在WebView中載入內容,防止使用者離開百度的網站。Uri.getAuthority()會返回一個URL的主機域名部分,我們會使用它檢測使用者點選的連結是否是百度的域名(www.baidu.com)。如果能夠確認連結指向的是百度的其他頁面,會返回false,從而允許WebView載入內容。如果不是,會通知使用者並返回true,然後通知WebViewClient應用程式已經處理了這個URL,不允許WebView載入它。
這項技術還能變得更加複雜,應用程式可以對URL做各種實際處理。通過自定義的處理方式,還可以在應用程式和WebView的內容之間打造一個完整的互動介面。

相關文章