[翻译] 对Android官方文档说爱你 -- WebView篇

— Android官方文档翻译,原文链接(科学上网)

前言

很多人都说官方文档是最好Android学习资料,但是由于种种原因:或无法科学上网(你懂的),或语言障碍,总是不能对它say love。本人是一名刚毕业的程序媛,英语六级水平,趁着大学英语还没有退化,本着大家互相学习的原则,尽可能多的翻译一些官方介绍,如果有错误请大家踊跃指出,谢谢。

《[翻译] 对Android官方文档说爱你 -- WebView篇》 WebView.png

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.

这是一个用于展示网页的视图控件。在这个类的基础上,你可以(译者注:调用)滚动你自带的web浏览器,也可以在Activity上简单地展示一些线上的内容。它使用WebKit渲染引擎显示web页面,并且包含了一些方法:通过历史记录向前或向后导航,放大和缩小,执行文本搜索等。

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:

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

This must be a child of the <manifest>
element.
For more information, read Building Web Apps in WebView.

注意,为了让你的Activity能够访问互联网并且能够加载Web页面到WebView中,你必须在你的Android清单文件中添加网络访问权限:

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

以上这条必须作为<manifest> 元素的子标签。
更多信息请阅读在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:

Uri uri = Uri.parse("http://www.example.com");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);  

See Intentfor more information.

默认情况下,WebView没有提供的类似浏览器部件(译者注:的设置),不支持JavaScript并且web页面报错也被忽略了。如果你的目标只是显示一些HTML 来作为你界面的一部分,这可能不错;除了阅读之外,用户不需要与网页交互,web页面也不需要与用户进行交互。如果你真的想要一个成熟的web浏览器,那么你可能需要通过一个URL意图调用浏览器应用程序,而不是使用WebView。例子:

Uri uri = Uri.parse("http://www.example.com");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);  

可以通过 Intent查看更多信息.

To provide a WebView in your own Activity, include a <WebView>
in your layout, or set the entire Activity window as a WebView during onCreate():

WebView webview = new WebView(this); 
setContentView(webview);

为了在你自己的Activity中使用WebView,需要在布局文件中添加一个< WebView >标签,或通过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("http://slashdot.org/"); 

// OR, you can also load from an HTML string: 
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 the JavaDocs forloadData() and loadDataWithBaseURL() for more info. 

然后加载所需的网页:

// 最简单的运用:注意,在这种情况下,如果在加载的页面出现错
// 误,这个异常不会被抛出(代码如下)
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的一些使用限制。
// 请查看loadData()和 loadDataWithBaseURL() 的Java文档去获取更多的信息。

<p>
A WebView has several customization points where you can add your own behavior. These are:

WebView有多种定制点,你可以添加你自己的行为。分别是:

  • 创建和设置WebChromeClient子类。这个类将在浏览器用户界面受到影响时被调用* (译者注:主要辅助WebView处理Javascript的对话框、网站图标、网站title、加载进度等) *,比如:界面更新时或在这里发送JavaScript alert时(参见 Debugging Tasks)。
  • 创建和设置 WebViewClient子类。这个类将在内容呈现受到影响时被调用*(译者注:主要处理各种通知、请求事件) *,比如,错误提交或表单提交时。你也可以在这里拦截URL加载(通过shouldOverrideUrlLoading())。
  • 修改WebSettings比如通过setJavaScriptEnabled()设置JavaScript可用。
  • 通过[addJavascriptInterface(Object, String)](https://developer.android.com/reference/android/webkit/WebView.html#addJavascriptInterface(java.lang.Object, java.lang.String))方法给WebView注入Java对象。这个方法允许您将Java对象注入到一个页面的JavaScript上下文,这样他们就可以在页面上通过JavaScript访问该对象* (译者注:即通过这个方法可以实现JS调用Java) *。
    <p>

Here’s a more complicated example, showing error handling, settings, and progress notification:

// Let's display the progress in the activity title bar, like the 
// browser app does. 
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%     
    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("http://developer.android.com/"); 

下面是一个较为复杂的例子,展示了错误处理、设置和进度提示:

// 我们在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) {     
    //  Activity和WebView的进度条以不同的方式计量进度
    //  进度条会在到达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("http://developer.android.com/"); 

<p>

Zoom

缩放

To enable the built-in zoom, set WebSettings.setBuiltInZoomControls(boolean)
(introduced in API level CUPCAKE).
NOTE: Using zoom if either the height or width is set to WRAP_CONTENT
may lead to undefined behavior and should be avoided.

通过 WebSettings.setBuiltInZoomControls(boolean)启用内置缩放设置。(在CUPCAKE版本的API中有介绍)。
注意:使用缩放后,如果高度或宽度设置为WRAP_CONTENT可能导致未定义行为,应该避免。

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 store等。它不共享浏览器应用的数据。

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 yourWebChromeClient to provide your own behaviour 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 theorientation 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丢到一边* (译者注:大约就是只要让Activity来处理配置变化就好了,不用设置WebView啦) *。它会自动调整本身。阅读 Handling Runtime Changes可以获得更多有关处理运行时变更的信息。

Building web pages to support different screen densities

构建web页面来支持不同的屏幕密度

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.

设备的屏幕密度由屏幕分辨率决定。低密度屏幕在每英寸屏幕上有很少的可用像素点,高密度屏幕在每英寸屏幕上通常有更多的可用像素点。屏幕的密度是很重要的,因为,在其他条件相同的情况下,一个用户界面元素(如按钮)的高度和宽度的定义是依据屏幕像素决定的,它会在低密度屏幕上显示的更大,在高密度屏幕上显示的更小。为简单起见,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会拉伸web页面,为的是让WebView能够大小匹配的显示在默认外观的中密度屏幕上。它以1.5 倍扩展显示在高密度屏幕上(因为它的像素更小)和0.75 倍扩展显示在低密度屏幕上(因为它的像素更大)。从 ECLAIR版本的API开始,WebView支持DOM,CSS和meta标签功能来帮助你(作为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 ofwindow.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.devicePixelRatioDOM属性。这个属性的值明确说明了用在当前设备上的默认比例因子。例如,如果window.devicePixelRatio的值是“1.0”,那么该设备被认为是中等密度(mdpi)设备并且默认缩放不应用于web页面;如果值是“1.5”,那么该设备被认为是高密度(hdpi)设备并且页面内容是按比例拉伸到1.5倍;如果值是“0.75”,那么该设备被认为是低密度(hdpi)设备并且页面内容是按比例拉伸到0.75倍。

  • 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:

<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.

  • -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 Video support

HTML5视频支持

In order to support inline HTML5 video in your application you need to have hardware acceleration turned on.

为了让你的应用支持内联HTML视频你需要选择硬件加速。

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)](https://developer.android.com/reference/android/webkit/WebChromeClient.html#onShowCustomView(android.view.View, android.webkit.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)](https://developer.android.com/reference/android/webkit/WebChromeClient.html#onShowCustomView(android.view.View, android.webkit.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)](https://developer.android.com/reference/android/webkit/WebChromeClient.html#onGeolocationPermissionsShowPrompt(java.lang.String, android.webkit.GeolocationPermissions.Callback)) method.

对于Android N和之后版本(API版本 > M)的应用程序,地理位置API只支持由安全源头发起的请求如https。这样的应用程序如果以非安全方式请求地理位置API会被自动拒绝,不会调用相应的 [onGeolocationPermissionsShowPrompt(String, GeolocationPermissions.Callback)](https://developer.android.com/reference/android/webkit/WebChromeClient.html#onGeolocationPermissionsShowPrompt(java.lang.String, android.webkit.GeolocationPermissions.Callback))方法。

Layout size

布局尺寸

It is recommended to set the WebView layout height to a fixed value or toMATCH_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.

建议使用固定值或MATCH_PARENT来代替WRAP_CONTENT设置WebView的高度。当使用 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.

  • HTML部分的高度要被设置为固定值。这就意味着元素相对于HTML的高度可能不正确。

  • For applications targetting KITKAT
    and earlier SDKs the HTML viewport meta tag will be ignored in order to preserve backwards compatibility.

  • 对于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的宽度被设置为 WRAP_CONTENT,那么它会尝试使用父控件的宽度来代替。

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:

 <meta-data android:name="android.webkit.WebView.MetricsOptOut"            android:value="true" /> 

Data will only be uploaded for a given app if the user has consented AND the app has not opted out.

在用户同意后,WebView可能会将匿名诊断数据上传到Google。这些数据可以帮助Google优化WebView。google将从每个实例化WebView的应用程序中收集数据,每个应用程序都可以通过在清单中做上以下标记来取消这一特性:

 <meta-data android:name="android.webkit.WebView.MetricsOptOut"            android:value="true" /> 

只有当用户已经同意,并且给定应用程序没有选择退出时,才可以上传数据。

本篇结束啦~~
如果有错误请告诉我,我会及时修改;
如果感觉还不错的话,请给我一个喜欢以表鼓励啦(__)

    原文作者:DenieceXu
    原文地址: https://www.jianshu.com/p/c956d50a0026
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞