迁移到 Android 4.4 中的 WebView  

您所在的位置:网站首页 分红转股的股票怎么交易 迁移到 Android 4.4 中的 WebView  

迁移到 Android 4.4 中的 WebView  

#迁移到 Android 4.4 中的 WebView  | 来源: 网络整理| 查看: 265

Android 4.4(API 级别 19)引入了基于 Chromium 的新版 WebView。此项变更会升级 WebView 的性能并标准化对 HTML5、CSS3 和 JavaScript 的支持,以与最新的网络浏览器保持一致。在 Android 4.4 及更高版本的设备上运行时,使用 WebView 的所有应用都将继承这些升级。

本文档介绍了关于 WebView 的其他变更,如果您将 targetSdkVersion 设置为“19”或更高版本,则应注意这些变更。

注意:如果您的 targetSdkVersion 设置为“18”或更低版本,则 WebView 将在“怪异模式”下尽可能紧密地运行,以避免上述某些行为变更,同时仍为应用提供性能和网络标准升级。不过要注意这一点,Android 4.4 根本不支持单列和窄列布局以及默认缩放级别,可能会存在未发现的其他行为差异,因此请务必在 Android 4.4 或更高版本上测试您的应用,即使 targetSdkVersion 设置为“18”或更低版本也是如此。

为了帮助您解决将应用迁移到 Android 4.4 中的 WebView 时可能遇到的任何问题,您可以调用 setWebContentsDebuggingEnabled() 以通过桌面设备上的 Chrome 启用远程调试。借助 WebView 中的这项新功能,您可以在 WebView 中运行时检查和分析网页内容、脚本和网络活动。如需了解详情,请参阅 Android 上的远程调试。

用户代理更改

如果您根据用户代理向 WebView 提供内容,则应注意用户代理字符串可能稍有变化,现在包含 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

如果您需要检索用户代理,但不需要为应用存储它或不想实例化 WebView,则应使用静态方法 getDefaultUserAgent()。不过,如果您打算替换 WebView 中的用户代理字符串,则可以改用 getUserAgentString()。

多线程和线程拦截

如果您从应用的界面线程之外的任何线程针对 WebView 调用方法,可能会导致意外结果。例如,如果您的应用使用多个线程,则可以使用 runOnUiThread() 方法确保代码在界面线程中执行:

Kotlin runOnUiThread { // Code for WebView goes here } Java runOnUiThread(new Runnable() { @Override public void run() { // Code for WebView goes here } });

另外,请确保您一定不会拦截界面线程。某些应用在等待 JavaScript 回调时会出现此错误。例如,不要使用如下代码:

Kotlin // This code is BAD and will block the UI thread webView.loadUrl("javascript:fn()") while (result == null) { Thread.sleep(100) } Java // This code is BAD and will block the UI thread webView.loadUrl("javascript:fn()"); while(result == null) { Thread.sleep(100); }

您可以改用新方法 evaluateJavascript() 来异步运行 JavaScript。

自定义网址处理

新的 WebView 会在请求资源和解析使用自定义网址架构的链接时应用其他限制。例如,如果您实现 shouldOverrideUrlLoading() 或 shouldInterceptRequest() 之类的回调,那么 WebView 仅针对有效网址调用它们。

如果您使用的是自定义网址架构或基准网址,并注意到您的应用接收的对这些回调的调用较少或无法在 Android 4.4 上加载资源,请确保请求按照 RFC 3986 的规定指定有效的网址。

例如,新的 WebView 可能不会针对如下链接调用您的 shouldOverrideUrlLoading() 方法:

Show Profile

用户点击此类链接后出现的结果可能会有所不同:

如果您通过调用 loadData() 或者包含无效或为 null 的基本网址的 loadDataWithBaseURL() 来加载网页,则不会在该页面上收到此类链接的 shouldOverrideUrlLoading() 回调。

注意:当您使用 loadDataWithBaseURL() 且基准网址无效或设为 null 时,您加载的内容中的所有链接都必须为绝对链接。

如果您通过调用 loadUrl() 加载页面或使用 loadDataWithBaseURL() 提供有效基准网址,则会收到页面上的此类链接的 shouldOverrideUrlLoading() 回调,但您收到的网址将是绝对网址(相对于当前页面)。例如,您收到的网址将为 "http://www.example.com/showProfile"(而不只是 "showProfile")。

您可以使用如下所示的自定义架构,而不是如上所述在链接中使用简单字符串:

Show Profile

然后,您可以在 shouldOverrideUrlLoading() 方法中处理此网址,如下所示:

Kotlin // The URL scheme should be non-hierarchical (no trailing slashes) const val APP_SCHEME = "example-app:" override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean { return if (url?.startsWith(APP_SCHEME) == true) { urlData = URLDecoder.decode(url.substring(APP_SCHEME.length), "UTF-8") respondToData(urlData) true } else { false } } Java // The URL scheme should be non-hierarchical (no trailing slashes) 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() 并设置由自定义架构和有效主机组成的基准网址,例如 "example-app:///"。例如:

Kotlin webView.loadDataWithBaseURL("example-app://example.co.uk/", HTML_DATA, null, "UTF-8", null) Java webView.loadDataWithBaseURL("example-app://example.co.uk/", HTML_DATA, null, "UTF-8", null);

有效主机名称应符合 RFC 3986 并且必须在末尾包含尾部斜杠,否则系统可能会丢弃来自已加载网页的所有请求。

视口更改 视口 target-densitydpi 不再受支持

以前,WebView 支持名为 target-densitydpi 的视口属性来帮助网页指定其预期的屏幕密度。此属性已不再受支持,您应迁移到使用标准解决方案来处理图片和 CSS,如WebView 中的精美像素风格界面中所述。

在视口较小时放大视口

以前,如果将视口宽度的值设置为小于或等于“320”,则它会设置为“device-width”;如果将视口高度的值设置为小于或等于 WebView 高度,则它会设置为“device-height”。不过,在新的 WebView 中运行时,系统会使用宽度值或高度值,并放大 WebView 以填充屏幕宽度。

不支持多视口标记

以前,如果您在网页中添加了多个视口标记,则 WebView 会合并所有标记中的属性。在新的 WebView 中,系统仅使用最后一个视口并忽略所有其他视口。

默认缩放级别已弃用

用于在页面上获取并设置初始缩放级别的 getDefaultZoom() 和 setDefaultZoom() 方法不再受支持,您应改为在网页中定义相应的视口。

注意:Android 4.4 及更高版本根本不支持这些 API。即使您的 targetSdkVersion 设置为“18”或更低版本,这些 API 也不会造成任何影响。

如需了解如何在 HTML 中定义视口属性,请参阅 WebView 中的精美像素风格界面。

如果无法在 HTML 中设置视口的宽度,则应调用 setUseWideViewPort() 以确保页面具有较大的视口。例如:

Kotlin webView.settings.apply { useWideViewPort = true loadWithOverviewMode = true } Java WebSettings settings = webView.getSettings(); settings.setUseWideViewPort(true); settings.setLoadWithOverviewMode(true); 样式更改 后台 CSS 简写形式会替换 background-size

Chrome 浏览器和其他浏览器采用这种方法已经有一段时间了,但现在如果您也指定了 background 样式,则 WebView 也会替换 background-size 的 CSS 设置。例如,此处的尺寸会重置为默认值:

.some-class { background-size: contain; background: url('images/image.png') no-repeat; }

解决方法是直接在两个属性之间来回切换。

.some-class { background: url('images/image.png') no-repeat; background-size: contain; } 尺寸采用 CSS 像素来代替屏幕像素

以前,尺寸参数(如 window.outerWidth 和 window.outerHeight)会以实际屏幕像素返回值。在新的 WebView 中,这些参数会根据 CSS 像素返回值。

尝试针对尺寸调整元素或其他计算使用并计算物理尺寸(以像素为单位)的做法通常不妥。不过,如果您停用了缩放功能并将初始比例设置为 1.0,则可以使用 window.devicePixelRatio 获取比例,然后用 CSS 像素值乘以该值。您也可以改为创建 JavaScript 绑定,从 WebView 本身查询像素尺寸。

如需了解详情,请参阅 quirksmode.org。

NARROW_COLUMNS 和 SINGLE_COLUMN 不再受支持

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

注意:Android 4.4 及更高版本根本不支持这些 API。即使您的 targetSdkVersion 设置为“18”或更低版本,这些 API 也不会造成任何影响。

您可以通过以下方式处理此更改:

更改应用的样式:

如果您可以控制页面上的 HTML 和 CSS,则可能会发现更改内容设计可能是最可靠的方法。例如,在您引用许可的屏幕上,您可能需要在 标记内封装文本,可以使用以下样式执行此操作:

如果您尚未为页面定义视口属性,这可能会非常有帮助。

使用新的 TEXT_AUTOSIZING 布局算法:

如果您使用窄列来提高移动设备上的各种桌面版网站的可读性,并且无法更改 HTML 内容,则新的 TEXT_AUTOSIZING 算法可能是 NARROW_COLUMNS 的合适替代方法。

此外,新的 WebView 也不支持之前已弃用的 SINGLE_COLUMN 值。

在 JavaScript 中处理触摸事件

如果您的网页直接在 WebView 中处理触摸事件,请确保您还一并处理 touchcancel 事件。在以下情况下,系统将调用 touchcancel,如果未收到调用,可能会导致出现问题:

用户触摸某个元素(系统因此调用 touchstart 和 touchmove)并滚动页面,从而导致系统抛出 touchcancel。 用户触摸某个元素(系统调用 touchstart),但系统未调用 event.preventDefault(),导致 touchcancel 提前抛出(因此 WebView 假定您不想使用触摸事件)。


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3