1. 程式人生 > >API 25 (Android 7.1.1 API) webkit.WebView——未完待續

API 25 (Android 7.1.1 API) webkit.WebView——未完待續

Android API 25 (Android 7.1.1) 

WebView

public class WebView

extends AbsoluteLayout implements ViewTreeObserver.OnGlobalFocusChangeListener,

ViewGroup.OnHierarchyChangeListener

java.lang.Object

   ↳android.webkit.WebView

【概述】

顯示網頁的檢視。此類是您可以滾動自己的Web瀏覽器或只顯示您的活動中的一些線上內容的基礎。 它使用WebKit渲染引擎來顯示網頁,幷包括通過歷史記錄向前和向後瀏覽,放大和縮小,執行文字搜尋等方法。

請注意,為了讓您的Activity訪問Internet並在WebView中載入網頁,您必須將INTERNET許可權新增到Android清單檔案中:

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

這必須是<manifest>元素的子元素。

有關更多資訊,請參閱 Building Web Apps in WebView

【基本用法】

預設情況下,WebView提供瀏覽器小部件,不支援JavaScriptweb頁面錯誤被忽略。如果你的目的是隻顯示一些

HTML 網頁作為UI介面的一部分

,這可能是好的。使用者不需要與網頁互動

如果你真的想要一個成熟的web瀏覽器,那麼你可能想和一個URL呼叫瀏覽器應用程式的意圖,而不是顯示

WebView。例如:

Uri uri = Uri.parse("http://www.example.com");

Intent intent = new Intent(Intent.ACTION_VIEW, uri);

startActivity(intent);

有關詳細資訊,請參閱Intent

要在自己的Activity中提供WebView,請在佈局中包含<WebView>,或在onCreate()中將整個活動視窗設定為

WebView

WebView webview = new WebView(this);

setContentView(webview);

然後載入所需的網頁:

//最簡單的用法:注意不會丟擲異常

//如果載入此頁面時出錯(見下文)。

  webview.loadUrl(“http://slashdot.org/”);

// 或者,您也可以載入HTML字串:

  String summary =“<html> <body>You scored<b> 192 </ b>points.</ body> </ html>”

  webview.loadData(summary,“text / html”,null);

// ...但是請注意這對HTML有限制。

//有關更多資訊,請參閱JavaDocs的loadData()和loadDataWithBaseURL()。

WebView有幾個自定義點,您可以新增自己的行為。 這些是:

· 建立和設定WebChromeClient子類。當瀏覽器的UI發生變化時呼叫,如:進度條更改、JavaScript的視窗。

(見Debugging Taskshttp://developer.android.com/tools/debugging/index.html)

· 建立和設定WebViewClient子類。主要處理解析,渲染網頁等瀏覽器做的事情也可以攔截URL載入(通過shouldOverrideUrlLoading())。

· 修改WebSettings,例如通過setJavaScriptEnabled()啟用JavaScript。

· 使用addJavascriptInterface(Object,String)方法將Java物件注入到WebView中。 此方法允許您將Java物件注入到頁面的JavaScript上下文中,以便可以通過頁面中的JavaScript訪問它們。

這裡有一個更復雜的示例,顯示錯誤處理,設定和進度通知:

//讓我們在活動標題欄中顯示進度,就像瀏覽器應用程式。

getWindow().requestFeature(Window.FEATURE_PROGRESS);

webview.getSettings().setJavaScriptEnabled(true);

final Activity activity = this;

webview.setWebChromeClient(new WebChromeClient() {

public void onProgressChanged(WebView view, int progress) {

//Activities和WebViews以不同的尺度衡量進度。

//當達到100%時,進度條將自動消失。

activity.setProgress(progress * 1000);

}

});

webview.setWebViewClient(new WebViewClient() {

public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {

      Toast.makeText(activity, "Oh no! " + description, Toast.LENGTH_SHORT).show();

    }

});

【縮放】

要啟用內建縮放,請設定WebSettings.setBuiltInZoomControls(boolean)(在API 3引入)。

注意:如果高度或寬度設定為WRAP_CONTENT,則使用縮放可能會導致未定義的行為,應該避免。

【Cookie和視窗管理】

為了安全起見,你的應用程式需要使用自己的快取,它不共享瀏覽器應用程式的資料。

預設情況下,通過HTML開啟新視窗的請求被忽略。無論是通過JavaScript還是由連線上的target屬性開啟,都是如此。你可以自定義WebChromeClient以提供您自己的行為,以開啟多個視窗,並以任何方式呈現它們。

當裝置定向或任何其他配置更改時,將銷燬並重新建立活動的標準行為。這將導致WebView重新載入當前頁面。

如果你不希望出現這種情況,您可以設定你的Activity來處理方向和鍵盤隱藏的更改,然後單獨退出WebView。它會根據需要自動重新適配自己。執行時如何處理配置更改請閱讀更多資訊,Handling Runtime Changes 。

【構建支援不同的螢幕密度的網頁】

裝置的螢幕密度基於螢幕解析度。低密度的螢幕每英寸具有較少的可用畫素,高密度的螢幕每英寸具有更多的畫素。螢幕的密度是很重要的,因為在其它條件相同的情況下,高度和寬度根據螢幕畫素定義的UI元素(例如按鈕)將在較低密度螢幕上顯得較大,而在較高密度螢幕上較小。為了簡單起見,Android將所有實際螢幕密度壓縮為三個廣義密度:高,中和低。

預設情況下,WebView縮放網頁,使其以與中等密度螢幕上預設外觀相匹配的尺寸繪製。 因此,它在高密度螢幕上應用1.5倍縮放(因為其畫素較小),在低密度螢幕上應用0.75倍縮放(因為其畫素更大)。 從API 5開始,WebView支援DOM,CSS和meta標籤的功能,以幫助您作為一個web開發目標不同的螢幕密度的螢幕。

以下是可用於處理不同螢幕密度的功能摘要:

window.devicePixelRatioDOM屬性。此屬性的值指定用於當前裝置的預設縮放因子。例如,如果

window.devicePixelRatio的值為“1.0”,則裝置被認為是中密度(mdpi)裝置,並且預設縮放不應用於網頁;如果值為“1.5”,則裝置被認為是高密度裝置(hdpi),並且頁面內容縮放為1.5倍;如果值為“0.75”,則裝置被認為是低密度裝置(ldpi),並且內容被縮放0.75倍。

-webkit-device-pixel-ratio CSS媒體查詢。使用此選項指定要使用此樣式表的螢幕密度。相應的值應為“0.75”,

“1”或“1.5”,以分別表示樣式適用於具有低密度,中密度或高密度螢幕的裝置。例如:

<link rel =“stylesheet”media =“screen and(-webkit-device-pixel-ratio:1.5)”href =“hdpi.css”/>

hdpi.css樣式表僅用於螢幕畫素比率為1.5的裝置,這是高密度畫素比率。

【HTML5視訊支援】

為了在您的應用程式中支援內嵌HTML5視訊,您需要啟用硬體加速。

【全屏支援】

為了支援全屏——視訊或其他HTML內容,您需要設定一個WebChromeClient,並實現onShowCustomView(View,WebChromeClient.CustomViewCallback)和onHideCustomView()。 如果缺少這兩種方法中的任一種,那麼將不允許web內容進入全屏。 或者,您可以使用getVideoLoadingProgressView()來自定義視訊正在載入時顯示的檢視。

【HTML5地理位置API支援】

對於面向Android N及更高版本(API級別> M)的應用,geolocation api僅在安全源(例如https)上受支援。 對於這樣的應用程式,對非安全源的地理位置API的請求被自動拒絕,而不呼叫相應的

onGeolocationPermissionsShowPrompt(String,GeolocationPermissions.Callback)方法。

【佈局尺寸】

建議將WebView佈局高度設定為固定值或MATCH_PARENT,而不是使用WRAP_CONTENT。 當對高度使用MATCH_PARENT時,沒有WebView的父級應該使用WRAP_CONTENT佈局高度,因為這可能會導致檢視大小不正確。

WebView的高度設定為WRAP_CONTENT會啟用以下行為:

·HTML主體佈局高度設定為固定值。 這意味著相對於HTML正文具有高度的元素可能無法正確調整大小。

·對於針對KITKAT和早期SDK的應用程式,HTML檢視meta標籤將被忽略,以保留向後相容性。

不支援使用WRAP_CONTENT的佈局寬度。 如果使用這樣的寬度,WebView將嘗試使用父級的寬度。

【指標】

當用戶同意時,WebView可能會將匿名診斷資料上傳到Google。 這些資料有助於Google改進WebView。 針對已例項化WebView的每個應用程式,基於每個應用程式收集資料。 個別應用程式可以在清單中加入以下標記,藉此停用這項功能:

<meta-data android:name =“android.webkit.WebView.MetricsOptOut”

android:value =“true”/>

只有在使用者同意並且應用尚未選擇停用的情況下,系統才會上傳指定應用的資料。

【巢狀類】

介面     WebView.FindListener

用於監聽查詢結果的介面。

類      WebView.HitTestResult

介面    WebView.PictureListener

此介面在API級別12中已棄用。此介面現已過時。

類      WebView.VisualStateCallback

回撥介面提供給postVisualStateCallback(long,WebView.VisualStateCallback),用於接收關於可視狀態的通知。

類      WebView.WebViewTransport

用於跨執行緒邊界返回WebView的傳輸物件。

【繼承自view.ViewGroup的XML屬性】

【繼承自view.View的XML屬性】

【公共建構函式】

WebView(Context context)

WebView(Context context, AttributeSet attrs)

WebView(Context context, AttributeSet attrs, int defStyleAttr)

WebView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)

WebView(Context context, AttributeSet attrs, int defStyleAttr, boolean privateBrowsing)

此建構函式在API級別17中已棄用。不再直接通過WebView支援私有瀏覽,將在以後的版本中刪除。 首選使用

WebSettings,WebViewDatabase,CookieManager和WebStorage來細粒度控制隱私資料。

【公共方法】

addJavascriptInterface

void addJavascriptInterface (Object object, String name)

API 1

將提供的Java物件注入到此WebView中。 使用提供的名稱將物件注入到主框架的JavaScript上下文中。 這允許從

JavaScript訪問Java物件的方法。 對於定位到API 17及更高版本的應用程式,只能使用JavaScript訪問使用

JavascriptInterface註釋的公共方法。 對於針對API 16或更低版本的應用程式,可以訪問所有公共方法(包括繼承

的方法),請參閱下面的重要安全說明以瞭解其含義。

請注意,注入的物件不會出現在JavaScript中,直到頁面是下一頁(重新載入。例如:

 class JsObject {

    @JavascriptInterface

    public String toString() { return "injectedObject"; }

 }

 webView.addJavascriptInterface(new JsObject(), "injectedObject");

 webView.loadData("", "text/html", null);

 webView.loadUrl("javascript:alert(injectedObject.toString())");

重要:

·此方法可用於允許JavaScript控制主機應用程式。這是一項強大的功能,但也會對面向JELLY_BEAN或更早版本的應用程式帶來安全風險。如果應用在執行Android 4.2之前版本的裝置上執行,那麼定位到JELLY_BEAN之後的版本的應用仍然會受到攻擊。使用此方法的最安全的方法是定位JELLY_BEAN_MR1並確保僅當在Android 4.2或更高版本上執行時才呼叫該方法。對於這些較舊的版本,JavaScript可以使用反射來訪問注入物件的公共欄位。在包含不受信任內容的WebView中使用此方法可能允許攻擊者以無意的方式操縱主機應用程式,以主機應用程式的許可權執行Java程式碼。在可能包含不受信任內容的WebView中使用此方法時請格外小心。

·JavaScript與此WebView的私有後臺執行緒上的Java物件進行互動。因此需要小心保持螺紋安全。

·Java物件的欄位不可訪問。

·對於針對API級別LOLLIPOP及以上的應用程式,注入Java物件的方法可以從JavaScript列舉。

canGoBack

boolean canGoBack ()

API 1

獲取此WebView是否具有後退歷史記錄項。

canGoForward

boolean canGoForward ()

API 1

獲取此WebView是否具有前進歷史項。

canGoBackOrForward

boolean canGoBackOrForward (int steps)

API 1

獲取頁面是否可以後退或前進給定數量的步驟。

canZoomIn

boolean canZoomIn ()

Added in API level 11,deprecated in API level 17.

獲取此WebView是否可以放大。

此方法在API級別17中已棄用。

這種方法容易由於網路呈現和UI執行緒之間的競爭條件而不準確; 推薦onScaleChanged(WebView,float,float)。

canZoomOut

boolean canZoomOut ()

Added in API level 11,deprecated in API level 17.

獲取此WebView是否可以縮小。

此方法在API級別17中已棄用。

這種方法容易由於網路呈現和UI執行緒之間的競爭條件而不準確; 推薦onScaleChanged(WebView,float,float)。

capturePicture

Picture capturePicture ()

Added in API level 11,deprecated in API level 19.

使用onDraw(Canvas)獲取WebView的點陣圖快照,或使用saveWebArchive(String)將內容儲存到檔案。

獲取捕獲此WebView的當前內容的新圖片。 圖片是正在顯示的整個文件,並且不限於此WebView當前顯示的區域。 此外,該圖片是靜態副本,並且不受稍後對正在顯示的內容的更改的影響。

請注意,由於內部更改,對於11和14之間(包括)的API級別,圖片不包括固定位置元素或可滾動div。

注意,從API 17返回的圖片只應該繪製到點陣圖支援的畫布 - 使用任何其他型別的畫布將涉及額外的轉換,在記憶體和效能的成本。 此外,返回的物件不支援createFromStream(InputStream)和writeToStream(OutputStream)方法。

clearCache

void clearCache (boolean includeDiskFiles)

API 1

清除資源快取記憶體。注意,快取是每個應用程式,因此這將清除所有使用的WebView的快取。

clearClientCertPreferences

void clearClientCertPreferences (Runnable onCleared)

API 21

清除儲存的客戶端證書首選項以響應繼續/取消客戶端證書請求。 請注意,Webview在收到ACTION_STORAGE_CHANGED意圖時會自動清除這些首選項。 偏好設定由嵌入程式應用程式建立的所有網路檢視共享。

clearFormData

void clearFormData ()

API 1

從當前關注的表單欄位(如果存在)中刪除自動完成彈出式視窗。注意這隻會影響自動完成彈出視窗的顯示,它不會從這個WebView的儲存中刪除任何儲存的表單資料。 要做到這一點,使用clearFormData()。

clearHistory

void clearHistory ()

API 1

告訴此WebView清除其內部後退/前進列表。

clearMatches

void clearMatches ()

API 3

清除由findAllAsync(String)建立的突出顯示的周圍文字匹配。

clearSslPreferences

void clearSslPreferences ()

API 1

清除儲存的SSL首選項表,以響應繼續執行SSL證書錯誤。

clearView

void clearView ()

Added in API level 11,deprecated in API level 18.

使用WebView.loadUrl(“about:blank”)可靠地重置檢視狀態和釋放頁面資源(包括任何正在執行的JavaScript)。

computeScroll

void computeScroll ()

API 1

如果需要,父程序呼叫以請求子程序更新mScrollX和mScrollY的值。 如果孩子使用Scroller物件來動畫滾動,通常會這樣做。

copyBackForwardList

WebBackForwardList copyBackForwardList()

API 1

獲取此WebView的WebBackForwardList。 這包含用於查詢歷史堆疊中的每個專案的後退/前進列表。 這是私有

WebBackForwardList的副本,因此它只包含當前狀態的快照。 對此方法的多個呼叫可能返回不同的物件。 從此方法返回的物件將不會更新以反映任何新狀態。

createPrintDocumentAdapter

PrintDocumentAdapter createPrintDocumentAdapter()

Added in API level 19,deprecated in API level 21.

使用createPrintDocumentAdapter(String),它需要使用者提供列印文件名稱。

createPrintDocumentAdapter

PrintDocumentAdapter createPrintDocumentAdapter (String documentName)

API 21

建立一個PrintDocumentAdapter,提供此Webview的內容以供列印。 介面卡通過將Webview內容轉換為PDF流來工作。 在轉換過程中無法繪製Web檢視 - 任何此類繪製未定義。 建議使用專用的離屏Webview進行列印。 如果需要,應用程式可以通過使用定製的PrintDocumentAdapter例項臨時隱藏可見的WebView,該例項包裝在返回的物件上並觀察onStart和onFinish方法。 有關詳細資訊,請參閱PrintDocumentAdapter。

createWebMessageChannel

WebMessagePort[] createWebMessageChannel ()

API 23

建立訊息通道以與JS通訊,並返回表示此訊息通道的端點的訊息埠。 這裡介紹了HTML5訊息通道功能

返回的訊息通道被糾纏並且已處於啟動狀態。

destroy

void destroy ()

API 1

銷燬此WebView的內部狀態。 在從檢視系統中刪除此WebView之後,應呼叫此方法。 在銷燬後,此WebView上不能呼叫其他方法。

dispatchKeyEvent

boolean dispatchKeyEvent (KeyEvent event)

API 1

將鍵事件分派到焦點路徑上的下一個檢視。此路徑從檢視樹的頂部向下延伸到當前聚焦的檢視。如果這個檢視有焦點,它會排程自己。否則,它將沿著焦點路徑分派下一個節點。此方法也會觸發任何鍵監聽器。

documentHasImages

void documentHasImages (Message response)

API 1

查詢文件以檢視其是否包含任何影象引用。訊息物件將被分派,arg1如果找到影象則設定為1,如果文件沒有引用任何影象,則為0。

enableSlowWholeDocumentDraw

void enableSlowWholeDocumentDraw ()

API 21

對於定位到L發行版的應用程式,WebView具有新的預設行為,通過智慧選擇需要繪製的HTML文件部分來減少記憶體佔用並提高效能。 這些優化對開發人員是透明的。 但是,在某些情況下,應用程式開發人員可能想要停用它們:

·當應用程式使用onDraw(Canvas)進行自己的繪圖並訪問頁面的可見部分以外的部分。

·當應用程式使用capturePicture()捕獲非常大的HTML文件。 請注意,capturePicture是一個已棄用的API。

啟用繪製整個HTML文件具有顯著的效能成本。 在建立任何WebView之前應該呼叫此方法。

evaluateJavascript

void evaluateJavascript (String script, ValueCallback<String> resultCallback)

API 19

非同步地在當前顯示的頁面的上下文中評估JavaScript。 如果非空,| resultCallback | 將呼叫從該執行返回的任何結果。 此方法必須在UI執行緒上呼叫,並且回撥將在UI執行緒上進行。

相容性說明。面向N或更高版本的應用程式,來自空WebView的JavaScript狀態不再在諸如loadUrl(String)之類的導航中持久儲存。 例如,在呼叫loadUrl(String)之前定義的全域性變數和函式不會存在於載入的頁面中。 應用程式應該使用addJavascriptInterface(Object,String)來跨導航儲存JavaScript物件。

findAddress

String findAddress(String addr)

獲取由物理位置的地址組成的第一個子字串。目前,只檢測美國的地址,包括:

·房子號碼

·街道名稱

·街道型別(道路,圓形等),拼寫或縮寫

·城市名稱

·一個州或領地,或者拼寫出來的,或者兩個字母的

·可選的5位數或9位數郵政編碼

所有名稱必須正確大寫,並且郵政編碼(如果存在)必須對該州有效。街道型別必須是標準的USPS拼寫或縮寫。 州或領地也必須使用USPS標準拼寫或縮寫。 房子號碼不能超過五位數。

findAll

int findAll (String find)

Added in API level 3,deprecated in API level 16.

首選findAllAsync(String)。

在頁面上查詢find的所有例項,並突出顯示它們。 通知任何已註冊的WebView.FindListener。

findAllAsync

void findAllAsync (String find)

API 16

在頁面上查詢find的所有例項,並以非同步方式突出顯示它們。 通知任何已註冊的WebView.FindListener。 對此的連續呼叫將取消任何未完成的搜尋。