1. 程式人生 > >在WebView中構建網路應用

在WebView中構建網路應用

原文連結地址

在WebView中構建網路應用

如果你想在你的客戶端應用上引入一個Web應用(僅僅是一個Web頁),你就可以使用WebView。WebView是一個允許你在你的Activity佈局中展示Web頁面的View類的實現類。它不包括一個完全開發的瀏覽器的任何功能,如導航欄或位址列。WebView所做的,僅僅是顯示一個Web頁面.

一個更加常見的使用WebView的場景是當你想要在你的應用中提供一些資訊,而這些資訊很可能需要更新時而使用WebView。就像使用者協議和使用者指南等。在你的應用中,你可以建立一個包含WebView的Activity,利用它來展示你的線上文件。

另一個WebView可能很有用的場景就是 你的應用需要對使用者提供一些資料,而這些資料需要你經常性的訪問網路來獲得,就像email一樣。在這種情況中,你會發現相比傳送一個網路請求,然後解析其中的資料最後將他們展示在你的佈局中來說,使用一個web 頁來展示使用者資料時十分簡單的。進而,你可以專門為Android裝置設計一個web頁,然後通過WebView在你的Android應用中載入這個頁面來實現。

這篇文章向你展示瞭如何啟用一個WebView,如何做一些額外的事情,就像處理介面導航,從Web頁繫結JavaScript到Android應用的客戶端程式碼中去。

為你的應用程式增加一個WebView

為了在你的應用中增加WebView,簡單的在佈局檔案中引入 <WebView>標籤就可以。例如,下面就是一個讓WebView充滿螢幕的佈局檔案。

<?xml version="1.0" encoding="utf-8"?>
<WebView  xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/webview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
/>

通過loadUrl()方法為WebView載入Web頁。例如:

WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.loadUrl("http://www.example.com");

在它開始工作之前,你的應用必須有訪問網路的許可權。為了獲得這一許可權,需要在你的manifest檔案中請求INTERNET許可權。例如:

<manifest ... >
    <uses-permission android:name="android.permission.INTERNET" />
    ...
</manifest>

這就是建立一個基本的展示Web頁的WebView你所需要做的全部的事情。

在WebView中使用JavaScript

如果你想在你的WebView中載入帶有JavaScript的Web頁,你必須讓你的WebView支援JavaScript。一旦JavaScript被啟用了,你就可以在你的應用程式碼和JavaScript程式碼中建立介面了。

啟用JavaScript

預設情況下,WebView中JavaScript是不啟用的。你可以通過依附於WebView的WebSettings類實現,使用webView 的getSetting()方法返回一個webSetting物件,呼叫setJavaScriptEnabled()來開啟JavaScript。

例如:

WebView myWebView = (WebView) findViewById(R.id.webview);
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);

WebSettings提供了各種各樣的你可能會發現很有用的其他設定。例如,如果你正在開發一個專門用WebView設計的Web應用,你通過setUserAgentString()方法自定義了一個一個使用者代理字串。通過在你的Web頁中查詢這個自定義的使用者代理字串來核實客戶端的請求是否來自的了Android應用。

將 JavaScript 程式碼繫結到 Android程式碼

當我們開發一個以WebView實現Web的Android應用時,你可以在你的javaScript程式碼和客戶端Android之前建立介面。例如你的JavaScript程式碼可以呼叫一段你的Android程式碼來啟動一個 Dialog,而不是通過在JavaScript中使用alert()函式實現。

為了在你的Android程式碼和JavaScript程式碼間繫結一個介面,需要呼叫addJavascriptInterface()方法,傳遞一個類例項到你繫結的JavaScript中,JavaScript可以呼叫以訪問該類的介面名稱。

public class WebAppInterface {
    Context mContext;

    /** Instantiate the interface and set the context */
    WebAppInterface(Context c) {
        mContext = c;
    }

    /** Show a toast from the web page */
    @JavascriptInterface
    public void showToast(String toast) {
        Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
    }
}

警告:如果你的 targetSdkVersion是17或者更高,你必須在你想要暴露給JavaScript的方法(方法必須是public方法)前加 @JavascriptInterface註解,如果你不提供這個註解,當在Android4.2或者更高的版本中執行該程式時,你的web 也將不能取得該方法。

在這個例子中,WebAppInterface類允許web頁通過使用showToast()方法建立一個Toast資訊。

你可以通過addJavascriptInterface()方法繫結這個類到執行在你的WebView中JavaScript上,並且以“Android”命名介面。

例如:

WebView webView = (WebView) findViewById(R.id.webview);
webView.addJavascriptInterface(new WebAppInterface(this), "Android");

這段程式碼為執行在WebView上的JavaScript建立了一個名為“Android”的介面,這時,你的Web應用可以訪問到

WebAppInterface類。類如,當用戶點選了一個按鈕,這裡有的HTML和JavaScript程式碼就會使用這個介面建立一個Toast訊息。

<input type="button" value="Say hello" onClick="showAndroidToast('Hello Android!')" />

<script type="text/javascript">
    function showAndroidToast(toast) {
        Androi.showToast(toast);
    }
</script>

這裡不需要在JavaScript中初始化你的“Android”介面,WebView自動的讓它在你的Web頁中可獲得。所以,在按鈕的點選事件中,showAndroidToast()方法使用“Android”介面來呼叫WebAppInterface.showToast()方法。

注意:繫結到JavaScript上的物件將會執行在另一個執行緒中,而不是在構造它的執行緒中執行。

警告:使用addJavascriptInterface()方法會允許JavaScript控制你的Android應用。這是一個很有用的特點,也是一個危險的安全問題。當WebView中的HTML程式碼不可信時(例如,HTML的一部分或全部是由未知的人或程序提供的)攻擊者可以植入HTML程式碼執行你的客戶端程式碼,這些程式碼可以是任意程式碼。正因為如此,除非你WebView中所有的HTML和JavaScript程式碼都是自己寫的,否則就不要使用addJavascriptInterface()方法。你也不應該讓使用者在你的WebView中導航到不屬於你的Web站點上。(相反的是,允許使用者使用預設瀏覽器應用來開啟外部連結–在預設情況下,使用者的瀏覽器可以開啟所有連結,所以,在以下情況時要小心處理導航介面)

處理頁面導航

當用戶在你的WebView中點選了Web頁中的一個連結,預設的行為是讓Android 系統啟動一個可以處理URLs的應用。通常情況下,預設的Web瀏覽器將會根據URL去載入。然而,你可以在你的WebView中重寫這個行為,讓連結在你的WebView中開啟。你可以允許使用者通過WebView中儲存的瀏覽歷史來通過導航欄進行前進或後退。

為了開啟被使用者點選的連結,簡單的為WebView提供了WebViewClient類,通過 setWebViewClient()方法獲得,例如:

WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.setWebViewClient(new WebViewClient());

就這樣,所有使用者點選的連結都將在你的WebView中載入。

如果你想對連結點選事件有更多的控制,建立你自己的WebViewClient 重寫 shouldOverrideUrlLoading()方法。例如:

private class MyWebViewClient extends WebViewClient {
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        if (Uri.parse(url).getHost().equals("www.example.com")) {
            // This is my web site, so do not override; let my WebView load the page
            return false;
        }
        // Otherwise, the link is not for a page on my site, so launch another Activity that handles URLs
        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
        startActivity(intent);
        return true;
    }
}

接下來,為你的WebView建立一個新的WebViewClient:

WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.setWebViewClient(new MyWebViewClient());

現在,每當使用者點選一個連結,系統就會呼叫 shouldOverrideUrlLoading()方法,去檢查是否URL的主機名稱可以匹配這個特殊的域名。如果確實匹配,方法會返回false,不會重寫URL,如果不匹配,就通過一個Intent,去啟動預設程式來解析URLs。

瀏覽網頁歷史記錄

當你的WebView重新載入了URL時,它會自動的儲存一個瀏覽的歷史記錄。你可以通過導航欄的後退和前進在歷史記錄的 goBack()goForward()方法中瀏覽。

例如,這裡是你的Activity能使用的裝置導航欄的後退按鈕的方法。

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    // Check if the key event was the Back button and if there's history
    if ((keyCode == KeyEvent.KEYCODE_BACK) && myWebView.canGoBack()) {
        myWebView.goBack();
        return true;
    }
    // If it wasn't the Back key or there's no web page history, bubble up to the default
    // system behavior (probably exit the activity)
    return super.onKeyDown(keyCode, event);
}

canGoBack()方法返回true代表這裡有使用者可以訪問的Web頁的歷史記錄。同樣的,你可以使用 canGoForward()方法來判斷是否有可以前進的歷史記錄。如果你不做這個檢查,一旦使用者到達了歷史記錄的底端 goBack()goForward() 方法將什麼也不會做。