【Android进阶篇】WebView显示网页详解

概述

WebViewAndroid用于显示网页的控件。通过WebView,我们可以查看本地的网页,也可以查看网络资源。
本文内容如下:

  1. 加载本地网页
  2. 加载网络资源
  3. WebView中使用JavaScriptCSS
  4. WebChromeClient介绍
  5. WebView的其它功能

一、加载本地网页

使用WebView加载本地网页时,需要把网页放到Android项目根目录下assets文件夹下,然后URL为:file:///android_asset/文件。
下面是示例:

1. 首先创建工程,这步简单;

2. 在activity_main界面文件中放好WebView控件,代码如下:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.mywebview.MainActivity" >

    <WebView
        android:id="@+id/webView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />

</RelativeLayout>

3. 创建文件Hello.html,放在assets文件夹下,hello.html内容如下:

<!DOCTYPE html>
<html>
<head><title>Hello</title></head>
<body>
Hello, WebView
</body>
</html>

只显示了一行:Hello, WebView

4. 下面是MainActivity代码:

public class MainActivity extends ActionBarActivity {
 
 private WebView webView;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //获取控件
        webView = (WebView) findViewById(R.id.webView);
        //装载URL
        webView.loadUrl("file:///android_asset/hello.html");
        //获取焦点
        webView.requestFocus();
    }
   
}

5. 运行后可看到结果如图:

加载本地文件非常简单,我们只要获取到控件后,使用loadUrl这个方法,WebView就自动地去把文件装载到界面里并进行解析。当然,我们的Demo也相当简单,没有用到jscss等文件。下面介绍一下如何访问网络URL。

二、访问网络资源

访问网络资源会稍微复杂一点。我们不仅需要设置URL,而且需要在AndroidMainfest里申请网络权限,最重要的一点,我们需要设置WebViewClient,即用什么应用打开一个URL,如果我们不设置,这个URL就不会被我们的WebView装载,而是由系统浏览器装载。下面来看一下示例,我们先看不设置WebViewClient的:

下面是MainActivity的部分代码:

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //获取控件
        webView = (WebView) findViewById(R.id.webView);
        //装载URL
        webView.loadUrl("http://www.baidu.com/");
        //获取焦点
        webView.requestFocus();
}

还需要在AndroidManifest中申请网络权限:
<uses-permission android:name="android.permission.INTERNET"/>

运行后,界面效果为:

应用会要我们选择使用什么浏览器打开URL,而不是就使用我们自己的WebView。

下面我们在MainActivity中加上设置WebViewClient的语句,WebViewClient是负责接收处理请求和通知(可以直接通过Eclipse的Open Declaration的方法看源码的注释):

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 获取控件
webView = (WebView) findViewById(R.id.webView);
// 装载URL
webView.loadUrl("http://www.baidu.com/");
// 设置WebViewClient来接收处理请求和通知
webView.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
// 返回true则表明使用的是WebView
return true;
}
});
// 获取焦点
webView.requestFocus();
}

运行后,结果为:

这就是上网成功了。

三、在WebView中使用JavaScriptCSS

WebView中使用css文件很容易,只需要在Html中引入一下或写一些style代码就好;但JavaScript就要多一点工作了。
WebView中使用JavaScript,我们首先需要使用WebSettingsWebView启动JavaScript功能,然后才能使用。另外,在JavaScript中很多功能在WebView中不能直接使用,比如常用的alert就不行,我们需要自己来实现,这个等下再讲。下面我们来实现在WebView中使用JavaScriptCSS

首先创建一个css文件style.css,和Hello.html文件位于同一目录,内容如下:

body {
 background:#bbbbbb;
 color:red;
}

Hello.html文件内容作一些修改:

<!DOCTYPE html>
<html>
<head>
<meta charset="gbk">
<link rel="stylesheet" href="style.css"></link>
<title>Hello</title></head>
</style>
<body>
<div id="x">Hello, WebView<div>
</body>
<script>
var obj = document.getElementById("x");
obj.innerHTML = "你好"; //将"Hello, WebView"改为"你好"
alert("你好");
console.log("你好");
</script>
</html>

如果成功执行,则"Hello, WebView"将改为"你好",可以先去尝试一下。下面在MainActivityWebView启用JavaScript

public class MainActivity extends ActionBarActivity {
 
 private WebView webView;
 
 private String localFile = "file:///android_asset/hello.html";
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 获取控件
        webView = (WebView) findViewById(R.id.webView);
        // 装载URL
        webView.loadUrl(localFile);
        // 设置WebViewClient来接收处理请求和通知
        webView.setWebViewClient(new WebViewClient(){
         @Override
         public boolean shouldOverrideUrlLoading(WebView view, String url) {
          view.loadUrl(url);
          // 返回true则表明使用的是WebView
                return true;
            }
        });
        //WebSettings负责管理WebView的一些状态,生命周期与WebView一致
        //在WebView生成时同时生成
        WebSettings settings = webView.getSettings();
        //使用WebSettings启用JavaScript
        settings.setJavaScriptEnabled(true);
       
        // 获取焦点
        webView.requestFocus();
    }
   
}

运行后结果:

JavaScriptCSS成功执行(alert除外,并没有弹出对话框)
注:html代码里面我设置的编码是GBK,这是因为我的Eclipse默认编码是GBK,所以一定要设置好自己对应的编码,不然中文会是乱码。

四、 WebChromeClient介绍

WebChromeClientChrome处理器,我们可以通过webView.setWebChromeClient(client)来设置,它是一个很重要的组件。通过这个组件我们可以实现JavaScript中的对话框(即alert)、网页加载进度条等。下面通过这个组件就来实现一下上文没能响应的alert函数以及在JavaScript调试过程中十分重要的console.log()函数。实现的方式就是在对应的方法里将JavaScript函数转换为Android里的组件实现。

MainActivity代码如下,细节写在了注释里:

        //设置WebChromeClient
        webView.setWebChromeClient(new WebChromeClient(){
         
         /**
          * 实现console.log():既然是日志,自然是用Android里的Log.d来实现
          */
         @Override
         public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
          // 直接输出信息即可
          Log.d("JavaScript", consoleMessage.message());
                return true;
            }
         
         /**
          * 实现alert(), 其实只要使用了WebChromeClient就有默认实现
          * 不过我们是以学习为目的,来学一下自己定制吧
          */
         @Override  
            public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {  
          //创建Android对话框来输出信息
                AlertDialog.Builder b = new AlertDialog.Builder(MainActivity.this)  
                        .setTitle("JavaScript对话框").setMessage(message)  
                        .setPositiveButton("ok",  
                                new AlertDialog.OnClickListener() {  
                                    @Override  
                                    public void onClick(DialogInterface dialog,  
                                            int which) {  
                                        result.confirm();
                                        dialog.dismiss();
                                    }  
                                });  
                b.create(); //创建对话框
                b.show();  	//显示对话框
                return true;  
            }
        });

日志输出:

Demo截图:

因为在Html中早就写好了alert和console.log,只是当时没有执行,所以不用修改其它的。从截图可看出,已经成功实现了alertconsole.log

如果想知道WebChromeClient还可以实现哪些功能,可以直接查看源码。

五、WebView的其它功能

WebView还有很多其它的功能,就不一一列举了,上述只讲了几个我觉得比较重要的,还有比如回退、前进、查看历史记录、设置WebView缓存等功能也是很重要的方法。