Android 之 用WebView显示网页
官方参考资料:WebView、Building Web Apps in WebView 。
一、综述
public class WebView extends AbsoluteLayout implements ViewTreeObserver.OnGlobalFocusChangeListener, ViewGroup.OnHierarchyChangeListener
在 android.webkit 包中, 继承关系如下:
android.webkit.WebView → android.widget.AbsoluteLayout → android.view.ViewGroup → android.view.View → android.view.View 。
WebView,用于在 Android 开发中,使用 WebKit 渲染引擎加载显示 Web 页面,包含浏览历史、放大和缩小、执行搜索文本等方法。
注意:为了 Activity 可接入网络权限并在 WebView 中加载网页,必须在 AndroidManifest.xml 文件中添加“网络许可权限”:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.sdis.sdfoodtransfer"
android:versionCode="1"
android:versionName="1.0.0.1">
...
<uses-permission android:name="android.permission.INTERNET" />
...
</manifest>
二、基本使用
默认情况下, WebView 控件不像浏览器那样,没有开启 JavaScript 功能并忽略网页错误。此情况只可用于显示 Html 内容页,不需要与用户交互时。如果想要一个完全的浏览器功能,使用 URL Intent 比使用 WebView 控件更好,URL Intent示例如下:
Uri uri = Uri.parse("http://www.example.com");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
注意:使用 URL Intent 方式会调用客户端浏览器打开 Web 页面。
在使用 WebView 时,可以在布局文件中包含<WebView>或者在Activity的onCreate()中设置窗口是一个WebView。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<!-- 显示网页 -->
<WebView
android:id="@+id/urlWeb"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginTop="10dp" />
</RelativeLayout>
后台代码实现,如下:
//使用布局页的情况
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.example);
WebView web=(WebView)findViewById(R.id.saleWeb);
}
//直接在onCreate()中渲染
@Override
protected void onCreate(Bundle savedInstanceState) {
WebView webview = new WebView(this);
setContentView(webview);
}
加载简单页面,如下:
// 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 for loadData() and loadDataWithBaseURL() for more info.
WebView 有几个自定义的地方,可以添加自定义的行为,如下:
[1] 创建和设置一个 WebChromeClient子类。这个类当影响浏览器 UI 的 something 发生时被调用,例如,进度更新 和 JavaScript 发送警报(见调试任务)。
[2] 创建和设置一个 WebViewClient 子类,当发生影响内容渲染的 things 时将被调用,例如,错误 或 表单提交。可以用来拦截URL加载(via shouldOverrideUrlLoading())。
[3] 修改 WebSettings,例如开启 JavaScript 用 setJavaScriptEnabled()。
[4] 通过 addJavascriptInterface(Object, String) 方法注入 Java 对象到 WebView 。此方法允许注入一个Java对象到网页的 JavaScript 的上下文,使它们可以被页面中的 JavaScript 访问。
如下是一个复杂些的例子,显示错误处理、设置和进度的通知:
// 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/");
三、Zoom
启用内置的缩放,设置 WebSettings.setBuiltInZoomControls(boolean)(包含的api版本是CUPCAKE)。
注意:如果宽或高设置为 WRAP_CONTENT 时使用缩放,可能会导致不可预知的行为,应当避免。
四、Cookie and window management
出于安全的原因,应用程序有它的缓存、cookie 贮存等。它不共享浏览器应用程序数据。
默认情况下,通过 HTML 请求打开一个新窗口会被忽略。不管是通过 JavaScript 打开还是通过目标属性连接,都会这样。可以自定义的 WebChromeClient 用来提供打开多个窗口的行为,并以任何你想要的方式渲染。
当设备屏幕方向发生变化或者其他配置改变时,一个Activity 的标准行为是被销毁和重建。这会让 WebView 去重新加载当前的页面。如果不想这样,可以设置Activity 去处理 orientation 和 keyboardHidden 的变化,只留下WebView 。它会自动重定向自己来适应变化。读取 Handling Runtime Changes 获取更多关于在运行时配置改变时如何处理的信息。
五、Building web pages to support different screen densities
一个设备的屏幕密度是基于屏幕分辨率。一个低密度屏幕每英寸有较少的像素,一个高密度的屏幕每英寸有更多像素。一个屏幕的密度是很重要的,在其他的条件相同下,一个UI元素(例如一个按钮)在通过设置屏幕像素定义高度和宽度时,在低密度的屏幕显示较大,而在高密度的屏幕显示较小。为简单起见,Android 定义所有屏幕密度为三个广义的密度:高,中,低。
默认情况下,WebView 缩放一个网页是为了以中等密度屏幕上的默认外观的大小来描绘渲染。因此,它适用在高密度屏幕 1.5 倍缩放(因为它的像素比较小),在低密度屏幕 0.75 倍的比例缩放(因为它的像素较大)。从 ECLAIR 的API开始,WebView 支持DOM、CSS和meta 标签帮助网页开发者实现屏幕适配不同屏幕密度。
以下是可以用来处理不同屏幕密度的摘要功能:
[1] window.devicePixelRatio 的 DOM 属性,它的属性值用于指定当前设备的默认缩放比例。例如,window.devicePixelRatio 的值是1.0,那么设备被认为是一个中密度(mdpi)设备,并且默认缩放比例与网页不适配;如果,它的值是1.5,则设备被认为是一个高密度设备(hdpi),并且网页内容缩放 1.5倍;如果它的值是0.75,则设备被认为是低密度设备(ldpi),并且内容缩放 0.75 倍。
[2] -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 视频,需要打开硬件加速。
七、Full screen support
为了支持视频或其他Html美容的全屏,需要设置一个实现 onShowCustomView(View, WebChromeClient.CustomViewCallback)和 onHideCustomView() 的 WebChromeClient。如果这两个方法有任何一个没有实现,那么网页内容不能全屏。当视频正在加载时,可以实现 getVideoLoadingProgressView() 来定义 View 来显示。
八、HTML5 Geolocation API support
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.
九、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.
Setting the WebView's height to WRAP_CONTENT enables the following behaviors:
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.
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.
十、Metrics
当用户同意后,WebView 可以上传匿名诊断数据到Google。这些数据帮助 Google 提升 WebView。数据收集基于每一个有 WebView 实例的 App 。可以通过在 AndroidManifest.xml 文件中添加如下标签,退出数据上传:
<meta-data android:name="android.webkit.WebView.MetricsOptOut" android:value="true" />
数据只有在用户同意并没有Opt退出时才会被上传。
十一、应用实例
用途一:加载本地/Web资源
(1)加载本地资源,将待加载的本地资源(如 example.html )存放在assets文件夹内,调用WebView的loadUrl()方法加载:
webView = (WebView) findViewById(R.id.webView);
webView.loadUrl("file:///android_asset/example.html");
(2)加载网络资源,直接调用WebView的loadUrl()方法调用资源地址加载:
webView = (WebView) findViewById(R.id.webView);
webView.loadUrl("http://baidu.com");
用途二:在程序内打开网页
创建一个自己的WebViewClient,通过setWebViewClient关联,代码如下:
package com.example.testopen; import android.app.Activity;
import android.os.Bundle;
import android.webkit.WebView;
import android.webkit.WebViewClient; public class MainActivity extends Activity {
private WebView webView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test);
init(); } private void init(){
webView = (WebView) findViewById(R.id.webView);
webView.loadUrl("http://baidu.com"); //WebView加载web资源
//覆盖WebView默认使用第三方或系统默认浏览器打开网页的行为,使网页用WebView打开
webView.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// TODO Auto-generated method stub
//返回值是true的时候控制去WebView打开,为false调用系统浏览器或第三方浏览器
view.loadUrl(url);
return true;
}
});
}
}
用途三:如果访问的页面中有Javascript,则webview必须设置支持Javascript
//import android.webkit.WebSettings;
//启用支持javascript
WebSettings settings = webView.getSettings();
settings.setJavaScriptEnabled(true);
用途四:如果希望浏览的网页后退而不是退出浏览器,需要WebView覆盖URL加载,让它自动生成历史访问记录,就可以通过前进或后退访问已访问过的站点,需要 android.view.KeyEvent 命名空间。
//改写物理按键——返回的逻辑
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
if(keyCode==KeyEvent.KEYCODE_BACK)
{
if(webView.canGoBack())
{
webView.goBack();//返回上一页面
return true;
}
else
{
System.exit();//退出程序
}
}
return super.onKeyDown(keyCode, event);
}
用途五:判断页面加载过程
webView.setWebChromeClient(new WebChromeClient() {
@Override
public void onProgressChanged(WebView view, int newProgress) {
// TODO Auto-generated method stub
if (newProgress == ) {
// 网页加载完成
} else {
// 加载中
}
}
});
用途六:缓存的使用
优先使用缓存:
webView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
不使用缓存:
webView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
Android 之 用WebView显示网页的更多相关文章
- HTML5学习总结-10 Android 控件WebView显示网页
WebView可以使得网页轻松的内嵌到app里,还可以直接跟js相互调用. webview有两个方法:setWebChromeClient 和 setWebClient 1)setWebClient: ...
- Android : 如何在WebView显示的页面中查找内容
Android : 如何在WebView显示的页面中查找内容 Author : Aoyousatuo Zhao http://blog.sina.com.cn/aoyousatuo WebView是A ...
- Android:控件WebView显示网页
WebView可以使得网页轻松的内嵌到app里,还可以直接跟js相互调用. webview有两个方法:setWebChromeClient 和 setWebClient setWebClient:主要 ...
- Android:控件WebView显示网页 -摘自网络
WebView可以使得网页轻松的内嵌到app里,还可以直接跟js相互调用. webview有两个方法:setWebChromeClient 和 setWebClient setWebClient:主要 ...
- 使用WebView显示网页
简单的页面跳转 package com.example.webtest; import java.security.PublicKey; import android.support.v7.app.A ...
- android中使用WebView请求网页
请求网页首先需要访问网络的权限,在AndroidManifest.xml添加如下内容: <uses-permission android:name="android.permissio ...
- Android 使用WebView显示网页
构建WebView就可以显示Web信息.因为我觉得这里会讲述很多方式来实现WebView,所以我决定为每一种方式创建一个对应的Activity,MainActivity通过Button可以点击进入对应 ...
- WebView 显示网页
1.布局 <?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:androi ...
- HTML5学习总结-11 IOS 控件WebView显示网页
一 加载外部网页 1.使用UIWebView加载网页 运行XCode 新建一个Single View Application . 2 添加安全消息 添加以下消息到项目的 Info.plist &l ...
随机推荐
- JavaScript 继承方式详解
js继承的概念 js里常用的如下两种继承方式: 原型链继承(对象间的继承)类式继承(构造函数间的继承) 由于js不像java那样是真正面向对象的语言,js是基于对象的,它没有类的概念.所以,要想实现继 ...
- 最精简的IOCP封装
最精简的IOCP封装,DELPHI XE8直接编译通过.Winsock2.pas即使用DELPHI自带的,相信XE7也能编译,或者XE6,XE5也能. 单说Winsock2.pas,我见过无数种版本的 ...
- 使用timer8秒读取一次方法进行操作
public void TestofTimer() { System.Timers.Timer tt = new System.Timers.Timer(); //获取或设置引发 Elapsed 事件 ...
- (高精度运算4.7.21)UVA 10106 Product(大数乘法)
package com.njupt.acm; import java.math.BigInteger; import java.util.Scanner; public class UVA_10106 ...
- MetaQ安装部署文档
一.MetaQ安装部署情况: 地点 IP Broker ID Master/Slave Slave ID:Group 合肥 192.168.52.23 Slave 1:meta-slave-group ...
- HDU 5776 sum (前缀和)
题意:给定 n 个数,和 m,问你是不是存在连续的数和是m的倍数. 析:考虑前缀和,如果有两个前缀和取模m相等,那么就是相等的,一定要注意,如果取模为0,就是真的,不要忘记了,我当时就没记得.... ...
- urlrewritingnet 域名http状态302 问题(转)
UrlRewritingNet is an Url rewriting tool for ASP .Net and Elmahis a module for logging unhandled err ...
- mybatis 注解快速上手
一.mybatis 简单注解 关键注解词 : @Insert : 插入sql , 和xml insert sql语法完全一样 @Select : 查询sql, 和xml select sql语法完全一 ...
- Oracle 触发器在日志管理开发中的应用
摘要: 本文讨论了利用数据库中的触发器对日志管理进行设计与实现的方法, 是对原来在客户端软件中编写日志管理方法的一种改进, 并给出了 Oracle9i 中的实例演示.关键词: Oracle; 触发器; ...
- 使用MySQL中的EXPLAIN解释命令来检查SQL
我们看到许多客户的系统因为SQL及数据库设计的很差所以导致许多性能上的问题,这些问题不好解决,但是可以采用一套简单的策略来检查生产系统,发现并纠正一些共性问题. 很显然,您应该尽最大努力设计出最好的数 ...