在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() 方法將什麼也不會做。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章