Android網(wǎng)絡(luò)應(yīng)用之在WebView中構(gòu)建Web應(yīng)用程序

assets 文件夾下的html訪問方式:"file:///android_asset/index.html"

如果要將Web應(yīng)用程序(或只是網(wǎng)頁(yè))作為客戶端應(yīng)用程序的一部分提供,可以使用WebView進(jìn)行操作。 WebView類是Android的View類的擴(kuò)展,它允許您將網(wǎng)頁(yè)顯示為活動(dòng)布局的一部分。 它不包括完全開發(fā)的Web瀏覽器的任何功能,例如導(dǎo)航控件或地址欄。 默認(rèn)情況下,所有WebView都會(huì)顯示一個(gè)網(wǎng)頁(yè)。
使用WebView的常見情況是您希望在應(yīng)用程序中提供可能需要更新的信息(例如最終用戶協(xié)議或用戶指南)。 在您的Android應(yīng)用程序中,您可以創(chuàng)建一個(gè)包含WebView的活動(dòng),然后使用它來顯示在線托管的文檔。
WebView可以幫助的另一種情況是,如果您的應(yīng)用程序向用戶提供總是需要Internet連接來檢索數(shù)據(jù)(如電子郵件)的數(shù)據(jù)。 在這種情況下,您可能會(huì)發(fā)現(xiàn)在您的Android應(yīng)用程序中構(gòu)建WebView更容易,該應(yīng)用程序顯示具有所有用戶數(shù)據(jù)的網(wǎng)頁(yè),而不是執(zhí)行網(wǎng)絡(luò)請(qǐng)求,然后解析數(shù)據(jù)并將其呈現(xiàn)在Android布局中。 相反,您可以設(shè)計(jì)適合Android設(shè)備的網(wǎng)頁(yè),然后在Android應(yīng)用程序中實(shí)現(xiàn)加載網(wǎng)頁(yè)的WebView。
本文檔介紹了如何開始使用WebView,以及如何處理頁(yè)面導(dǎo)航,以及如何將Web頁(yè)面中的JavaScript綁定到Android應(yīng)用程序中的客戶端代碼

將WebView添加到您的應(yīng)用程序

要將WebView添加到應(yīng)用程序中,只需將<WebView>元素添加到活動(dòng)布局中即可。 例如,這里是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"
/>

要在WebView中加載網(wǎng)頁(yè),請(qǐng)使用loadUrl()。 例如:

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

然而,在此之前,您的應(yīng)用程序必須能夠訪問Internet。 要獲取Internet訪問權(quán)限,請(qǐng)?jiān)谇鍐挝募姓?qǐng)求INTERNET權(quán)限。 例如:.

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

這就是顯示網(wǎng)頁(yè)的基本W(wǎng)ebView所需要的。

在WebView中使用JavaScript

如果您計(jì)劃在WebView中加載的網(wǎng)頁(yè)使用JavaScript,則必須為WebView啟用JavaScript。 啟用JavaScript后,您還可以在應(yīng)用程序代碼和JavaScript代碼之間創(chuàng)建接口。

啟用JavaScript

默認(rèn)情況下,WebView中的JavaScript被禁用。 您可以通過附加到WebView的WebSettings啟用它。 您可以使用getSettings()檢索WebSettings,然后使用setJavaScriptEnabled()啟用JavaScript。

例如:

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

WebSettings可以訪問您可能會(huì)發(fā)現(xiàn)有用的各種其他設(shè)置。 例如,如果您正在開發(fā)專門針對(duì)Android應(yīng)用程序中的WebView設(shè)計(jì)的Web應(yīng)用程序,則可以使用setUserAgentString()定義自定義用戶代理字符串,然后在網(wǎng)頁(yè)中查詢自定義用戶代理,以驗(yàn)證 請(qǐng)求您的網(wǎng)頁(yè)的客戶端實(shí)際上是您的Android應(yīng)用程序。

將JavaScript代碼綁定到Android代碼

在開發(fā)專門針對(duì)Android應(yīng)用程序中的WebView設(shè)計(jì)的Web應(yīng)用程序時(shí),您可以在JavaScript代碼和客戶端Android代碼之間創(chuàng)建界面。 例如,您的JavaScript代碼可以調(diào)用Android代碼中的方法來顯示對(duì)話框,而不是使用JavaScript的alert()函數(shù)。

要綁定JavaScript和Android代碼之間的新界面,請(qǐng)調(diào)用addJavascriptInterface(),傳遞一個(gè)類實(shí)例以綁定到您的JavaScript和JavaScript可以調(diào)用以訪問該類的接口名稱。

例如,您可以在Android應(yīng)用程序中包含以下類:

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設(shè)置為17或更高版本,則必須將@JavascriptInterface注釋添加到您希望JavaScript可用的任何方法(該方法也必須是公共的)。 如果您不提供注釋,則在Android 4.2或更高版本上運(yùn)行時(shí),您的網(wǎng)頁(yè)無法訪問該方法。
在此示例中,WebAppInterface類允許網(wǎng)頁(yè)使用showToast()方法創(chuàng)建Toast消息。

您可以將此類綁定到使用addJavascriptInterface()在WebView中運(yùn)行的JavaScript,并將其命名為Android。 例如:

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

這將為WebView中運(yùn)行的JavaScript創(chuàng)建一個(gè)名為Android的界面。 此時(shí),您的Web應(yīng)用程序可以訪問WebAppInterface類。 例如,以下是一些HTML和JavaScript,當(dāng)用戶單擊按鈕時(shí),使用新界面創(chuàng)建吐司信息:

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

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

沒有必要從JavaScript初始化Android界面。 WebView自動(dòng)使您的網(wǎng)頁(yè)可用。 所以,點(diǎn)擊按鈕,showAndroidToast()函數(shù)使用Android界面來調(diào)用WebAppInterface.showToast()方法。
注意:綁定到您的JavaScript的對(duì)象在另一個(gè)線程中運(yùn)行,而不是在其構(gòu)造的線程中運(yùn)行。
注意:使用addJavascriptInterface()允許JavaScript控制您的Android應(yīng)用程序。 這可能是非常有用的功能或危險(xiǎn)的安全問題。 當(dāng)WebView中的HTML不可信(例如,一部分或全部HTML由未知人員或進(jìn)程提供)時(shí),攻擊者可以包括執(zhí)行客戶端代碼的HTML,以及攻擊者選擇的任何代碼。 因此,除非您寫入WebView中顯示的所有HTML和JavaScript,否則不應(yīng)使用addJavascriptInterface()。 您也不應(yīng)該允許用戶導(dǎo)航到您自己的WebView內(nèi)的其他網(wǎng)頁(yè)(而不是允許用戶的默認(rèn)瀏覽器應(yīng)用程序打開外部鏈接) - 默認(rèn)情況下,用戶的Web瀏覽器會(huì)打開所有URL鏈接,因此 只有當(dāng)您按照以下部分的描述處理頁(yè)面導(dǎo)航時(shí),請(qǐng)小心)

處理頁(yè)面導(dǎo)航

當(dāng)用戶從WebView中的網(wǎng)頁(yè)單擊鏈接時(shí),默認(rèn)行為是啟動(dòng)一個(gè)處理URL的應(yīng)用程序。 通常,默認(rèn)Web瀏覽器打開并加載目標(biāo)URL。 但是,您可以覆蓋WebView的此行為,因此在WebView中打開鏈接。 然后,您可以允許用戶通過WebView維護(hù)的網(wǎng)頁(yè)歷史向后和向后瀏覽。
要打開用戶點(diǎn)擊的鏈接,只需使用setWebViewClient()為您的WebView提供一個(gè)WebViewClient。 例如:

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

就這樣 現(xiàn)在 用戶所有點(diǎn)擊的鏈接都會(huì)在你的WebView

如果您想要更多地控制加載點(diǎn)擊的鏈接的位置,請(qǐng)創(chuàng)建自己的WebViewClient來覆蓋shouldOverrideUrlLoading()方法。 例如:

private class MyWebViewClient extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            if (Uri.parse(url).getHost().equals("www.example.com")) {
                // 這是我的網(wǎng)站,所以不要重寫; 讓我的WebView加載頁(yè)面
                return false;
            }
            // 否則,該鏈接不是我的網(wǎng)站上的頁(yè)面,因此啟動(dòng)另一個(gè)處理URL的活動(dòng)
            Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
            startActivity(intent);
            return true;
        }
    }

然后為WebView創(chuàng)建一個(gè)新的WebViewClient實(shí)例:

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

現(xiàn)在當(dāng)用戶單擊鏈接時(shí),系統(tǒng)調(diào)用shouldOverrideUrlLoading(),它檢查URL主機(jī)是否與特定域匹配(如上定義)。 如果它匹配,那么該方法返回false,以便不覆蓋URL加載(它允許WebView像往常一樣加載URL)。 如果URL主機(jī)不匹配,則創(chuàng)建Intent以啟動(dòng)用于處理URL的默認(rèn)活動(dòng)(解析為用戶的默認(rèn)Web瀏覽器)。

瀏覽網(wǎng)頁(yè)歷史記錄

當(dāng)您的WebView覆蓋URL加載時(shí),它會(huì)自動(dòng)累積訪問的網(wǎng)頁(yè)的歷史記錄。 您可以通過goBack()和goForward()向后和向前瀏覽歷史記錄。
例如,您的“活動(dòng)”可以使用“設(shè)備返回”按鈕向后導(dǎo)航:

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

如果用戶訪問實(shí)際的網(wǎng)頁(yè)歷史記錄,canGoBack()方法返回true。 同樣,您可以使用canGoForward()來檢查是否存在轉(zhuǎn)發(fā)歷史記錄。 如果您不執(zhí)行此檢查,則一旦用戶到達(dá)歷史記錄的末尾,goBack()或goForward()不執(zhí)行任何操作。

在Android4.4上的WebView

Android 4.4(API級(jí)別19)引入了基于Chromium的新版本的WebView。 此更改將針對(duì)HTML5,CSS3和JavaScript的WebView性能和標(biāo)準(zhǔn)支持進(jìn)行升級(jí),以配合最新的Web瀏覽器。 任何使用WebView的應(yīng)用程序?qū)⒃贏ndroid 4.4及更高版本上運(yùn)行時(shí)繼承這些升級(jí)。
本文檔描述了如果將targetSdkVersion設(shè)置為“19”或更高版本,您應(yīng)該注意的WebView的其他更改。
注意:如果您的targetSdkVersion設(shè)置為“18”或更低版本,則WebView將以“怪異”模式運(yùn)行,以避免在盡可能接近的情況下,盡可能避免一些行為變化,同時(shí)仍然為應(yīng)用程序提供性能和Web標(biāo)準(zhǔn)升級(jí)。 不過,請(qǐng)注意,Android 4.4中根本不支持單列和窄欄列布局和默認(rèn)縮放級(jí)別,并且還可能存在尚未識(shí)別的其他行為差異,因此請(qǐng)確保在Android 4.4或更高版本上測(cè)試您的應(yīng)用程序,即使 您將targetSdkVersion設(shè)置為“18”或更低。
為了幫助您解決在Android 4.4中將應(yīng)用程序遷移到WebView時(shí)遇到的任何問題,您可以通過調(diào)用setWebContentsDebuggingEnabled()來啟用桌面上的Chrome的遠(yuǎn)程調(diào)試。 WebView中的新功能允許您在WebView中運(yùn)行時(shí)檢查和分析Web內(nèi)容,腳本和網(wǎng)絡(luò)活動(dòng)。 有關(guān)詳細(xì)信息,請(qǐng)參閱Android上的遠(yuǎn)程調(diào)試。

用戶代理更改

如果您根據(jù)用戶代理向WebView提供內(nèi)容,則應(yīng)注意用戶代理字符串稍有更改,現(xiàn)在包括Chrome版本:
Mozilla/5.0 (Linux; Android 4.4; Nexus 4 Build/KRT16H) AppleWebKit/537.36
(KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Mobile Safari/537.36
如果您需要檢索用戶代理,但不需要為應(yīng)用程序存儲(chǔ)或不想實(shí)例化WebView,則應(yīng)使用靜態(tài)方法getDefaultUserAgent()。 但是,如果您打算覆蓋WebView中的用戶代理字符串,則可能需要使用getUserAgentString()。

多線程和線程阻塞

如果您從除應(yīng)用程序的UI線程之外的任何線程調(diào)用WebView方法,可能會(huì)導(dǎo)致意外的結(jié)果。 例如,如果您的應(yīng)用程序使用多個(gè)線程,則可以使用runOnUiThread()方法來確保您的代碼在UI線程上執(zhí)行:
還要確保你永遠(yuǎn)不會(huì)阻止UI線程。 某些應(yīng)用程序出現(xiàn)此錯(cuò)誤的情況是等待JavaScript回調(diào)。 例如,不要使用這樣的代碼:

webView.loadUrl("javascript:fn()");
while(result == null) {
  Thread.sleep(100);
}

您可以使用一種新方法evaluateJavascript()來異步運(yùn)行JavaScript。

自定義URL處理

新的WebView在請(qǐng)求資源并解析使用自定義URL方案的鏈接時(shí),會(huì)附加其他限制。 例如,如果您實(shí)現(xiàn)回調(diào),例如shouldOverrideUrlLoading()或shouldInterceptRequest(),則WebView將僅調(diào)用有效的URL。

如果您使用自定義URL方案或基本URL,并注意到您的應(yīng)用程序在這些回調(diào)中接收的呼叫較少或在Android 4.4上無法加載資源,請(qǐng)確保請(qǐng)求指定符合RFC 3986的有效URL。

例如,新的WebView可能不會(huì)像這樣的鏈接調(diào)用你的shouldOverrideUrlLoading()方法:
<a href="showProfile">Show Profile</a>
用戶點(diǎn)擊此鏈接的結(jié)果可能有所不同:
如果通過使用無效或空的基本URL調(diào)用loadData()或loadDataWithBaseURL()來加載頁(yè)面,那么您將不會(huì)收到該頁(yè)面上此類鏈接的shouldOverrideUrlLoading()回調(diào)。
注意:當(dāng)您使用loadDataWithBaseURL()并且基本URL無效或設(shè)置為null時(shí),正在加載的內(nèi)容中的所有鏈接必須是絕對(duì)的。
如果您通過調(diào)用loadUrl()或通過loadDataWithBaseURL()提供有效的基本URL來加載頁(yè)面,那么您將收到該頁(yè)面上此類型鏈接的shouldOverrideUrlLoading()回調(diào),但您收到的URL將是絕對(duì)的,相對(duì)于 當(dāng)前頁(yè)面。 例如,您收到的URL將是“http://www.example.com/showProfile”而不是“showProfile”。
而不是如上所示在鏈接中使用簡(jiǎn)單的字符串,您可以使用自定義方案,如下所示:
<a href="example-app:showProfile">Show Profile</a>
然后,您可以在您的shouldOverrideUrlLoading()方法中處理此URL,如下所示:

private static final String APP_SCHEME = "example-app:";

@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
    if (url.startsWith(APP_SCHEME)) {
        urlData = URLDecoder.decode(url.substring(APP_SCHEME.length()), "UTF-8");
        respondToData(urlData);
        return true;
    }
    return false;
}

如果您不能修改HTML,那么您可以使用loadDataWithBaseURL()并設(shè)置由自定義方案和有效主機(jī)(例如“example-app:// <valid_host_name> /”)組成的基本URL。 例如:
webView.loadDataWithBaseURL("example-app://example.co.uk/", HTML_DATA,
null, "UTF-8", null);

有效的主機(jī)名應(yīng)符合RFC 3986的要求,并且最后包括尾部的斜杠很重要,否則可能會(huì)丟棄來自加載的頁(yè)面的任何請(qǐng)求。

視口更改

不再支持視口target-densitydpi
以前,WebView支持一個(gè)名為target-densitydpi的視口屬性,以幫助網(wǎng)頁(yè)指定其預(yù)期的屏幕密度。 此屬性不再受支持,您應(yīng)該遷移到使用圖像和CSS的標(biāo)準(zhǔn)解決方案,如WebView中的Pixel-Perfect UI中所述。

視口縮小時(shí)放大

以前,如果將視口寬度設(shè)置為小于或等于“320”的值,則將其設(shè)置為“device-width”,如果將視口高度設(shè)置為小于或等于WebView高度的值 將設(shè)置為“device-height”。 但是,當(dāng)在新的WebView中運(yùn)行時(shí),會(huì)粘貼寬度或高度值,WebView放大以填充屏幕寬度

不支持多個(gè)視口標(biāo)簽

以前,如果您在網(wǎng)頁(yè)中包含多個(gè)視口標(biāo)簽,則WebView將合并所有標(biāo)簽的屬性。 在新的WebView中,僅使用最后一個(gè)視口,并忽略所有其他視口。

默認(rèn)縮放已棄用

getDefaultZoom()和setDefaultZoom()用于獲取和設(shè)置頁(yè)面上的初始縮放級(jí)別已不再受支持,您應(yīng)該在網(wǎng)頁(yè)中定義相應(yīng)的視口。

注意:Android 4.4及更高版本不支持這些API。 即使您的targetSdkVersion設(shè)置為“18”或更低,這些API也不起作用。
有關(guān)如何在HTML中定義視口屬性的信息,請(qǐng)?jiān)赪ebView中閱讀Pixel-Perfect UI。

如果您無法在HTML中設(shè)置視口的寬度,那么您應(yīng)該調(diào)用setUseWideViewPort()來確保頁(yè)面被賦予更大的視口。 例如:
WebSettings settings = webView.getSettings();
settings.setUseWideViewPort(true);
settings.setLoadWithOverviewMode(true);
造型變化
背景CSS簡(jiǎn)寫覆蓋了背景大小
Chrome和其他瀏覽器的行為已經(jīng)有一段時(shí)間了,但是如果您還指定了背景樣式,那么WebView也將覆蓋背景大小的CSS設(shè)置。 例如,這里的大小將被重置為默認(rèn)值:
.some-class {
background-size: contain;
background: url('images/image.png') no-repeat;
}
修復(fù)是簡(jiǎn)單地切換兩個(gè)屬性。 以這種方式行事一段時(shí)間,但是如果您還指定了背景樣式,那么WebView還將覆蓋背景大小的CSS設(shè)置。 例如,這里的大小將被重置為默認(rèn)值:
.some-class {
background: url('images/image.png') no-repeat;
background-size: contain;
}
尺寸為CSS像素而不是屏幕像素
以前,諸如window.outerWidth和window.outerHeight之類的大小參數(shù)在實(shí)際的屏幕像素中返回一個(gè)值。在新的WebView中,這些返回基于CSS像素的值。

通常不好的做法是嘗試計(jì)算尺寸元素或其他計(jì)算的物理尺寸(以像素為單位)。但是,如果禁用縮放,并將初始化設(shè)置為1.0,則可以使用window.devicePixelRatio獲取縮放比例,然后將CSS像素值乘以該像素值。相反,您還可以創(chuàng)建一個(gè)JavaScript綁定,以從WebView自身查詢像素大小。

有關(guān)更多信息,請(qǐng)參閱quirksmode.org。

不再支持NARROW_COLUMNS和SINGLE_COLUMN
新的WebView不支持WebSettings.LayoutAlgorithm的NARROW_COLUMNS值。

注意:Android 4.4及更高版本不支持這些API。即使您的targetSdkVersion設(shè)置為“18”或更低,這些API也不起作用。

您可以通過以下方式處理此更改:

更改應(yīng)用程序的樣式:
如果您可以控制頁(yè)面上的HTML和CSS,可能會(huì)發(fā)現(xiàn)改變內(nèi)容的設(shè)計(jì)可能是最可靠的方法。例如,對(duì)于您引用許可證的屏幕,您可能需要在< pre>標(biāo)簽之間進(jìn)行換行,您可以使用以下樣式:
<pre style="word-wrap: break-word; white-space: pre-wrap;">
如果您尚未定義頁(yè)面的視口屬性,這可能會(huì)特別有用。
使用新的TEXT_AUTOSIZING布局算法:
如果您使用窄列作為使廣泛的桌面版網(wǎng)站在移動(dòng)設(shè)備上更易于閱讀的方式,并且您無法更改HTML內(nèi)容,則新的TEXT_AUTOSIZING算法可能是NARROW_COLUMNS的替代方案。
此外,新的WebView中也不支持SINGLE_COLUMN值(以前已不推薦使用)。

處理JavaScript中的觸摸事件
如果您的網(wǎng)頁(yè)直接處理WebView中的觸摸事件,請(qǐng)確保您還處理了touchcancel事件。觸摸屏有幾種情況會(huì)被調(diào)用,如果沒有收到,可能會(huì)導(dǎo)致問題:

一個(gè)元素被觸摸(所以touchstart和touchmove被調(diào)用),頁(yè)面被滾動(dòng),導(dǎo)致一個(gè)觸摸屏被拋出。
觸摸一個(gè)元素(touchstart被調(diào)用),但是沒有調(diào)用event.preventDefault(),從而足夠早就觸發(fā)了觸發(fā)事件(所以WebView假設(shè)你不想消耗觸摸事件)。

調(diào)試Web程序

如果您使用運(yùn)行Android 4.4或更高版本的設(shè)備測(cè)試您的網(wǎng)絡(luò)應(yīng)用程序,則可以使用Chrome開發(fā)人員工具在WebView中遠(yuǎn)程調(diào)試網(wǎng)頁(yè),同時(shí)繼續(xù)支持舊版Android。 有關(guān)詳細(xì)信息,請(qǐng)參閱Android上的遠(yuǎn)程調(diào)試。

如果您沒有運(yùn)行Android 4.4或更高版本的設(shè)備,則可以使用控制臺(tái)JavaScript API調(diào)試JavaScript,并將輸出消息查看到logcat。 如果您熟悉使用Firebug或Web Inspector調(diào)試網(wǎng)頁(yè),那么您可能熟悉使用控制臺(tái)(如console.log())。 Android的WebKit框架支持大多數(shù)相同的API,因此您可以在Android瀏覽器或自己的WebView中調(diào)試時(shí)從網(wǎng)頁(yè)接收日志。 本文檔介紹如何使用控制臺(tái)API進(jìn)行調(diào)試。

在Android瀏覽器中使用控制臺(tái)API

當(dāng)調(diào)用控制臺(tái)函數(shù)(在DOM的window.console對(duì)象中)時(shí),輸出將顯示在logcat中。 例如,如果您的網(wǎng)頁(yè)執(zhí)行以下JavaScript:
console.log("Hello World");
然后logcat消息看起來像這樣:
Console: Hello World http://www.example.com/hello.html :82
根據(jù)您使用的Android版本,郵件的格式可能會(huì)有所不同。 在Android 2.1及更高版本上,來自Android瀏覽器的控制臺(tái)消息被標(biāo)記為名稱“browser”。 在Android 1.6及更低版本上,Android瀏覽器消息被標(biāo)記為名稱“WebCore”。

Android的WebKit不會(huì)實(shí)現(xiàn)其他桌面瀏覽器中可用的所有控制臺(tái)API。 但是,您可以使用基本的文本記錄功能:
console.log(String)
console.info(String)
console.warn(String)
console.error(String)
其他控制臺(tái)功能不會(huì)引起錯(cuò)誤,但可能與其他Web瀏覽器的期望不同。

在WebView中使用控制臺(tái)API

在WebView中調(diào)試時(shí),還支持上述所有控制臺(tái)API。 如果您要定位Android 2.1(API級(jí)別7)及更高版本,則必須提供實(shí)現(xiàn)onConsoleMessage()方法的WebChromeClient,以便控制臺(tái)消息出現(xiàn)在logcat中。 然后,使用setWebChromeClient()將WebChromeClient應(yīng)用到WebView。

例如,為了支持API級(jí)別7,這是onConsoleMessage(String,int,String)的代碼可能如下所示:

WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.setWebChromeClient(new WebChromeClient() {
  public void onConsoleMessage(String message, int lineNumber, String sourceID) {
    Log.d("MyApplication", message + " -- From line "
                         + lineNumber + " of "
                         + sourceID);
  }
});

但是,如果您的最低支持版本是API級(jí)別8或更高版本,那么您應(yīng)該實(shí)現(xiàn)onConsoleMessage(ConsoleMessage)。 例如:

WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.setWebChromeClient(new WebChromeClient() {
  public boolean onConsoleMessage(ConsoleMessage cm) {
    Log.d("MyApplication", cm.message() + " -- From line "
                         + cm.lineNumber() + " of "
                         + cm.sourceId() );
    return true;
  }
});

ConsoleMessage還包括一個(gè)MessageLevel對(duì)象來指示正在傳遞的控制臺(tái)消息的類型。 您可以使用messageLevel()來查詢消息級(jí)別,以確定消息的嚴(yán)重性,然后使用適當(dāng)?shù)腖og方法或采取其他適當(dāng)?shù)牟僮鳌?/p>

無論您是使用onConsoleMessage(String,int,String)還是onConsoleMessage(ConsoleMessage),當(dāng)您在網(wǎng)頁(yè)中執(zhí)行控制臺(tái)方法時(shí),Android都會(huì)調(diào)用相應(yīng)的onConsoleMessage()方法,以便您可以報(bào)告錯(cuò)誤。 例如,使用上面的示例代碼,將打印出如下所示的logcat消息:
Hello World -- From line 82 of http://www.example.com/hello.html

Web應(yīng)用程序的最佳做法

開發(fā)用于移動(dòng)設(shè)備的網(wǎng)頁(yè)和網(wǎng)絡(luò)應(yīng)用程序與開發(fā)典型桌面網(wǎng)絡(luò)瀏覽器的網(wǎng)頁(yè)相比,具有不同的挑戰(zhàn)。 為了幫助您開始使用,以下是您應(yīng)遵循的實(shí)踐列表,以便為Android和其他移動(dòng)設(shè)備提供最有效的Web應(yīng)用程序。
將移動(dòng)設(shè)備重定向到您的網(wǎng)站的專用移動(dòng)版本
使用服務(wù)器端重定向,您可以通過幾種方法將請(qǐng)求重定向到您的網(wǎng)站的移動(dòng)版本。 大多數(shù)情況下,這通過“嗅探”Web瀏覽器提供的用戶代理字符串來完成。 要確定是否為您的站點(diǎn)提供移動(dòng)版本,您應(yīng)該只是在用戶代理中查找與移動(dòng)設(shè)備類似的“移動(dòng)”字符串。 如果需要,您還可以識(shí)別用戶代理字符串中的特定操作系統(tǒng)(例如“Android 2.1”)。
注意:應(yīng)提供全尺寸網(wǎng)站(如平板電腦)的大屏幕Android設(shè)備不會(huì)在用戶代理中包含“移動(dòng)”字符串,而其余的用戶代理字符串大部分相同。 因此,根據(jù)用戶代理中是否存在“移動(dòng)”字符串,交付您的網(wǎng)站的移動(dòng)版本非常重要。
使用適合移動(dòng)設(shè)備的有效標(biāo)記DOCTYPE
用于移動(dòng)網(wǎng)站的最常用的標(biāo)記語(yǔ)言是XHTML Basic。 此標(biāo)準(zhǔn)確保您的網(wǎng)站在移動(dòng)設(shè)備上最有效的特定標(biāo)記。 例如,它不允許在移動(dòng)設(shè)備上表現(xiàn)不佳的HTML框架或嵌套表。 與DOCTYPE一起,請(qǐng)務(wù)必為文檔(如UTF-8)聲明適當(dāng)?shù)淖址幋a。
例如:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN"
"http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">
還要確保您的網(wǎng)頁(yè)標(biāo)記對(duì)聲明的DOCTYPE有效。 使用驗(yàn)證器,例如http://validator.w3.org可用的驗(yàn)證器。
使用視口元數(shù)據(jù)來正確調(diào)整您的網(wǎng)頁(yè)大小
在您的文檔<head>中,您應(yīng)該提供元數(shù)據(jù),指定瀏覽器的視口如何呈現(xiàn)您的網(wǎng)頁(yè)。 例如,您的視口元數(shù)據(jù)可以指定瀏覽器視口的高度和寬度,初始網(wǎng)頁(yè)縮放以及目標(biāo)屏幕密度。
例如:
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
有關(guān)如何為Android設(shè)備使用視口元數(shù)據(jù)的更多信息,請(qǐng)閱讀從Web應(yīng)用程序定位屏幕。
避免多個(gè)文件請(qǐng)求
由于移動(dòng)設(shè)備的連接速度通常遠(yuǎn)低于臺(tái)式機(jī),所以您應(yīng)該盡可能快地加載您的網(wǎng)頁(yè)。加速它的一種方法是避免在<head>中加載額外的文件,如樣式表和腳本文件。相反,直接在<head>(或<body>的末尾)直接在頁(yè)面加載之前不需要的腳本提供您的CSS和JavaScript?;蛘?,您應(yīng)該通過使用Minify等工具壓縮文件來優(yōu)化文件的大小和速度。
使用垂直線性布局
避免用戶在瀏覽網(wǎng)頁(yè)時(shí)向左右滾動(dòng)。上下滾動(dòng)對(duì)用戶來說更容易,并使您的網(wǎng)頁(yè)更簡(jiǎn)單。
有關(guān)創(chuàng)建優(yōu)秀移動(dòng)Web應(yīng)用程序的更全面的指南,請(qǐng)參閱W3C的移動(dòng)網(wǎng)絡(luò)最佳實(shí)踐。關(guān)于提高網(wǎng)站速度(適用于移動(dòng)和桌面)的其他指導(dǎo),請(qǐng)參閱Yahoo!的卓越績(jī)效指南和Google速度教程,讓我們使網(wǎng)絡(luò)更快。

以上為官方翻譯,如有翻譯不正確地方望指正。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,781評(píng)論 25 709
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,506評(píng)論 19 139
  • 前言 總結(jié) Android WebView 常用的相關(guān)知識(shí)點(diǎn),令包含以下干貨內(nèi)容分析:Js注入漏洞、WebView...
    無名小子的雜貨鋪閱讀 70,110評(píng)論 17 169
  • 世界七大奇跡之一的馬丘比丘的名頭實(shí)在太大,以至于前來庫(kù)斯科的游客都忽略了另一個(gè)世界之最——彩虹圣山,這個(gè)世界上最特...
    薄暮初陽(yáng)閱讀 1,227評(píng)論 11 17
  • 1.一個(gè)由小寫字母組成的字符串可以看成一些同一字母的最大碎片組成的。例如,"aaabbaaac"是由下面碎片組成的...
    雨y飄零久閱讀 103評(píng)論 0 0

友情鏈接更多精彩內(nèi)容