webview最全面詳解(一)瞭解官方文件
簡單介紹
WebView是手機中內建了一款高效能 webkit 核心瀏覽器,在 SDK 中封裝的一個元件。沒有提供位址列和導航欄,WebView只是單純的展示一個網頁介面。在開發中經常都會用到。
顯示和渲染Web頁面
直接使用html檔案(網路上或本地assets中)作佈局
可和JavaScript互動呼叫
WebView控制元件功能強大,除了具有一般View的屬性和設定外,還可以對url請求、頁面載入、渲染、頁面互動進行強大的處理。
本文翻譯官方文件認識和了解webview。
翻譯
官方文件 (自備梯子)
A View that displays web pages. This class is the basis upon which you can roll your own web browser or simply display some online content within your Activity. It uses the WebKit rendering engine to display web pages and includes methods to navigate forward and backward through a history, zoom in and out, perform text searches and more.
一個用來展示網頁的view控制元件,在這個類的基礎上,你可以在你的activity中使用系統自帶瀏覽器或者簡單的展示一些線上的內容。
Note that, in order for your Activity to access the Internet and load web pages in a WebView, you must add the INTERNET permissions to your Android Manifest file:
請注意,為了讓您的Activity能訪問網路並在WebView中載入網頁,您必須將INTERNET許可權新增到您的Android Manifest檔案中:
<uses-permission android:name="android.permission.INTERNET" />
This must be a child of the element.
For more information, read Building Web Apps in WebView.
這條必須作為 元素的子標籤。
更多資訊請閱讀用WebView構建 Web應用程式。
Basic usage
By default, a WebView provides no browser-like widgets, does not enable JavaScript and web page errors are ignored. If your goal is only to display some HTML as a part of your UI, this is probably fine; the user won’t need to interact with the web page beyond reading it, and the web page won’t need to interact with the user. If you actually want a full-blown web browser, then you probably want to invoke the Browser application with a URL Intent rather than show it with a WebView. For example:
預設情況下,webview並不提供類似瀏覽器的不見,不支援JavaScript 並且忽略網頁錯誤。如果你的目的是僅僅顯示一些HTML作為你的UI的一部分,那可能不錯,使用者閱讀網頁而不需要與之互動,網頁也不需要和使用者互動。
如果你真的想要一個完整的Web瀏覽器,那你可能需要通過一個URL intent呼叫瀏覽器應用程式而不是在WebView中顯示它,
例如:
Uri uri = Uri.parse("https://www.example.com");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
See Intent for more information.
To provide a WebView in your own Activity, include a in your layout, or set the entire Activity window as a WebView during onCreate():
請參閱意圖獲取更多資訊。
要在你的activity中支援webview,需要在layout中新增標籤,或者在 onCreate()方法中將整個activity視窗設定為一個webview。
WebView webview = new WebView(this);
setContentView(webview);
Then load the desired web page:
然後載入所需網頁
// Simplest usage: note that an exception will NOT be thrown
// if there is an error loading this page (see below).
// 最簡單的應用:注意在這種情況下,如果在載入的頁面出現錯
// 誤,這個異常不會被丟擲(如下)
webview.loadUrl("https://example.com/");
// OR, you can also load from an HTML string:
//而或,你也可以載入HTML字串
String summary = "<html><body>You scored <b>192</b> points.</body></html>";
webview.loadData(summary, "text/html", null);
// ... although note that there are restrictions on what this HTML can do.
// See loadData(String, String, String) and loadDataWithBaseURL(String, String, String, String, String) for more info.
// Also see loadData(String, String, String) for information on encoding special characters.
當然,要注意的是載入HTML是有限制的
請查閱loadData(String, String, String)和loadDataWithBaseURL(String, String, String, String, String)文件獲取更多資訊。
有關編碼特殊字元的資訊,另請參閱loadData(String,String,String)。
A WebView has several customization points where you can add your own behavior. These are:
Creating and setting a WebChromeClient subclass. This class is called when something that might impact a browser UI happens, for instance, progress updates and JavaScript alerts are sent here (see Debugging Tasks).
Creating and setting a WebViewClient subclass. It will be called when things happen that impact the rendering of the content, eg, errors or form submissions. You can also intercept URL loading here (via shouldOverrideUrlLoading()).
Modifying the WebSettings, such as enabling JavaScript with setJavaScriptEnabled().
Injecting Java objects into the WebView using the addJavascriptInterface(Object, String) method. This method allows you to inject Java objects into a page’s JavaScript context, so that they can be accessed by JavaScript in the page.
Here’s a more complicated example, showing error handling, settings, and progress notification:
webview有一些可以自定義的地方,你可以自定義自己的方法。這些分別是:
建立和設定一個WebChromeClient WebChromeClient 類。當某些可能影響瀏覽器使用者介面的事件發生時會呼叫此類,例如,傳送進度更新和JavaScript彈出alert的時候(請參閱除錯任務)。
(譯者注:WebChromeClient是輔助WebView處理Javascript的對話方塊,網站圖示,網站title,載入進度等 )
建立和設定一個WebViewClient 類,當影響內容呈現的事情發生時,它會被呼叫,例如提交錯誤或表單。 你也可以在這裡攔截URL載入(通過 shouldOverrideUrlLoading()]
(譯者注:WebViewClient就是幫助WebView處理各種通知、請求事件的)
// Let's display the progress in the activity title bar, like the
// browser app does.
//讓我們像瀏覽器程式一樣在activity標題欄展示載入進度
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 and WebViews measure progress with different scales.
// The progress meter will automatically disappear when we reach 100%
//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();
}
});
webview.loadUrl("https://developer.android.com/");
Zoom
縮放
Note: Using zoom if either the height or width is set to WRAP_CONTENT may lead to undefined behavior and should be avoided.
Cookie and window management
Cookie和視窗管理
For obvious security reasons, your application has its own cache, cookie store etc.—it does not share the Browser application’s data.
出於安全的考慮,你的應用有自己的快取,cookie儲存——它不與瀏覽器應用共享資料。
By default, requests by the HTML to open new windows are ignored. This is true whether they be opened by JavaScript or by the target attribute on a link. You can customize your WebChromeClient to provide your own behavior for opening multiple windows, and render them in whatever manner you want.
預設情況下,HTML發出的開啟新視窗的請求會被忽略。 無論它們是由JavaScript開啟還是由連結上的目標屬性開啟,都是如此。 您可以自定義您的WebChromeClient以規定你自己的行為以開啟多個視窗,並以你想要的任何方式呈現它們。
The standard behavior for an Activity is to be destroyed and recreated when the device orientation or any other configuration changes. This will cause the WebView to reload the current page. If you don’t want that, you can set your Activity to handle the orientation and keyboardHidden changes, and then just leave the WebView alone. It’ll automatically re-orient itself as appropriate. Read Handling Runtime Changes for more information about how to handle configuration changes during runtime.
對於activity的標準行為來說,當裝置方向或任何其他配置更改時,其都將被銷燬並重建。這將導致webview去過載當前介面,如果你不希望如此,你可以設定你的Activity來處理orientation和keyboardHidden變化,不用理會WebView。 它會自動適當地重新定位自己。 閱讀 Handling Runtime Changes 來獲取有關如何處理執行時配置更改的更多資訊。
‘
’
Building web pages to support different screen densities
構建網頁適配不同螢幕密度
The screen density of a device is based on the screen resolution. A screen with low density has fewer available pixels per inch, where a screen with high density has more — sometimes significantly more — pixels per inch. The density of a screen is important because, other things being equal, a UI element (such as a button) whose height and width are defined in terms of screen pixels will appear larger on the lower density screen and smaller on the higher density screen. For simplicity, Android collapses all actual screen densities into three generalized densities: high, medium, and low.
一個裝置的螢幕密度是基於螢幕解析度。低密度的螢幕每英寸有較少的可用畫素點,高密度的通常很明顯的螢幕每英寸有較多的畫素點。螢幕密度是很重要的,在其他的條件相同下,一個用螢幕畫素定義和設定高度和寬度的UI元素(例如一個按鈕),在低密度的螢幕顯示較大,而在高密度的螢幕顯示較小。為了簡單,Android 將所有螢幕密度分為三個廣義的密度:高,中,低。
By default, WebView scales a web page so that it is drawn at a size that matches the default appearance on a medium density screen. So, it applies 1.5x scaling on a high density screen (because its pixels are smaller) and 0.75x scaling on a low density screen (because its pixels are bigger). Starting with API level ECLAIR, WebView supports DOM, CSS, and meta tag features to help you (as a web developer) target screens with different screen densities.
預設情況下,WebView會縮放網頁,以便在中等密度螢幕上以與預設外觀相匹配的尺寸繪製網頁。 因此,它在高密度螢幕上應用1.5倍縮放(因為其畫素點較小),在低密度螢幕上縮放0.75倍(因為其畫素點較大)。 從API為ECLAIR開始,WebView支援DOM,CSS和meta tag標籤功能,以幫助你(Web開發人員)適配不同螢幕密度的螢幕。
Here’s a summary of the features you can use to handle different screen densities:
以下是可用於處理不同螢幕密度的功能摘要:
The window.devicePixelRatio DOM property. The value of this property specifies the default scaling factor used for the current device. For example, if the value of window.devicePixelRatio is “1.0”, then the device is considered a medium density (mdpi) device and default scaling is not applied to the web page; if the value is “1.5”, then the device is considered a high density device (hdpi) and the page content is scaled 1.5x; if the value is “0.75”, then the device is considered a low density device (ldpi) and the content is scaled 0.75x.
window.devicePixelRatio DOM屬性。 此屬性的值指定用於當前裝置的預設比例因子。 例如,如果window.devicePixelRatio的值為“1.0”,則該裝置被視為中等密度(mdpi)裝置,並且預設縮放不會應用於網頁; 如果該值是“1.5”,則該裝置被認為是高密度裝置(hdpi),並且頁面內容被縮放為1.5倍; 如果該值為“0.75”,則該裝置被認為是低密度裝置(ldpi),並且該內容被縮放為0.75x。
The -webkit-device-pixel-ratio CSS media query. Use this to specify the screen densities for which this style sheet is to be used. The corresponding value should be either “0.75”, “1”, or “1.5”, to indicate that the styles are for devices with low density, medium density, or high density screens, respectively. For example:
The-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" />
The hdpi.css stylesheet is only used for devices with a screen pixel ration of 1.5, which is the high density pixel ratio.
hdpi.css樣式表僅用於螢幕畫素比為1.5的裝置,即高密度螢幕。
HTML5 Video support
HTML5 視訊支援
In order to support inline HTML5 video in your application you need to have hardware acceleration turned on.
為了在你的應用程式中支援嵌入式HTML5視訊,你需要開啟硬體加速。
Full screen support
全屏支援
In order to support full screen — for video or other HTML content — you need to set a WebChromeClient and implement both onShowCustomView(View, WebChromeClient.CustomViewCallback) and onHideCustomView(). If the implementation of either of these two methods is missing then the web contents will not be allowed to enter full screen. Optionally you can implement getVideoLoadingProgressView() to customize the View displayed whilst a video is loading.
為了支援全屏 - 播放視訊或展示其他的HTML內容 - 你需要設定WebChromeClient並實現onShowCustomView(View,WebChromeClient.CustomViewCallback)和onHideCustomView()。 如果缺少這兩種方法中的任何一種,網頁內容將不被允許進入全屏模式。 此外,你可以通過實現getVideoLoadingProgressView()方法,來自定義載入視訊時顯示的檢視。
HTML5 Geolocation API support
HTML5 地理位置API 支援
For applications targeting Android N and later releases (API level > M) the geolocation api is only supported on secure origins such as https. For such applications requests to geolocation api on non-secure origins are automatically denied without invoking the corresponding onGeolocationPermissionsShowPrompt(String, GeolocationPermissions.Callback) method.
對於面向Android N及更高版本(API級別> M)的應用程式,地理位置api僅在安全來源(如https)的請求受支援。 對於此類應用程式,在不呼叫相應的onGeolocationPermissionsShowPrompt(String,GeolocationPermissions.Callback)方法的情況下,會自動拒絕在非安全來源上對地理位置api的請求。
Layout size
佈局尺寸
It is recommended to set the WebView layout height to a fixed value or to MATCH_PARENT instead of using WRAP_CONTENT. When using MATCH_PARENT for the height none of the WebView’s parents should use a WRAP_CONTENT layout height since that could result in incorrect sizing of the views.
推薦設定webview的layout height設定為固定值或者設定為MATCH_PARENT而不是WRAP_CONTENT。當高度使用MATCH_PARENT時,WebView的父級都不應使用WRAP_CONTENT佈局高度,因為這可能會導致檢視大小不正確。
Setting the WebView’s height to WRAP_CONTENT enables the following behaviors:
設定webview的高度為WRAP_CONTENT 可能將會導致以下行為:
The HTML body layout height is set to a fixed value. This means that elements with a height relative to the HTML body may not be sized correctly.
For applications targeting KITKAT and earlier SDKs the HTML viewport meta tag will be ignored in order to preserve backwards compatibility.
HTML的body高度設定為固定值。 這意味著和HTML body高度有關的元素的尺寸可能不正確。
對於面向KITKAT和更早SDK的應用程式,為了保持向後相容性,HTML檢視元標籤將被忽略。
Using a layout width of WRAP_CONTENT is not supported. If such a width is used the WebView will attempt to use the width of the parent instead.
不支援使用WRAP_CONTENT的佈局寬度。 如果使用這樣的寬度,WebView將嘗試使用父寬度。
Metrics
資料收集
WebView may upload anonymous diagnostic data to Google when the user has consented. This data helps Google improve WebView. Data is collected on a per-app basis for each app which has instantiated a WebView. An individual app can opt out of this feature by putting the following tag in its manifest’s element:
當用戶同意時,WebView可能會將匿名診斷資料上傳到Google。 這些資料有助於Google改進WebView。 例項化WebView的每個應用程式,都會被收集資料。 每個應用程式都可以通過在清單的元素中加入以下標籤來取消此功能:
<manifest>
<application>
...
<meta-data android:name="android.webkit.WebView.MetricsOptOut"
android:value="true" />
</application>
</manifest>
Data will only be uploaded for a given app if the user has consented AND the app has not opted out.
只有在使用者同意並且應用程式未退出的情況下,資料才會上傳。
Safe Browsing
安全瀏覽
With Safe Browsing, WebView will block malicious URLs and present a warning UI to the user to allow them to navigate back safely or proceed to the malicious page.
藉助安全瀏覽功能,WebView將阻止惡意網址並向用戶顯示警告使用者介面,允許他們安全地導航返回或者是進入惡意頁面。
Safe Browsing is enabled by default on devices which support it. If your app needs to disable Safe Browsing for all WebViews, it can do so in the manifest’s element:
安全瀏覽預設情況下在支援它的裝置上啟用。 如果您的應用需要禁用所有WebView的安全瀏覽,則可以在manifest的元素中執行此操作:
<manifest>
<application>
...
<meta-data android:name="android.webkit.WebView.EnableSafeBrowsing"
android:value="false" />
</application>
</manifest>