现在的位置: 首页 > 综合 > 正文

WebView

2013年08月07日 ⁄ 综合 ⁄ 共 13654字 ⁄ 字号 评论关闭

WebView(网络视图)能加载显示网页,可以将其视为一个浏览器。它使用了WebKit渲染引擎加载显示网页,实现WebView有以下两种不同的方法:
第一种方法的步骤:
1.在要Activity中实例化WebView组件:WebView webView = new WebView(this);
2.调用WebView的loadUrl()方法,设置WevView要显示的网页:
  互联网用:webView.loadUrl("http://www.google.com");
  本地文件用:webView.loadUrl("file:///android_asset/XX.html"); 本地文件存放在:assets 文件中
3.调用Activity的setContentView( )方法来显示网页视图
4.用WebView点链接看了很多页以后为了让WebView支持回退功能,需要覆盖覆盖Activity类的onKeyDown()方法,如果不做任何处理,点击系统回退剪键,整个浏览器会调用finish()而结束自身,而不是回退到上一页面
5.需要在AndroidManifest.xml文件中添加权限,否则会出现Web page not available错误。
  <uses-permission android:name="android.permission.INTERNET" />
下面是具体例子:
MainActivity.java
package com.android.webview.activity; 
 
import android.app.Activity; 
import android.os.Bundle; 
import android.view.KeyEvent; 
import android.webkit.WebView; 
 
public class MainActivity extends Activity { 
    private WebView webview; 
    @Override
    public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        //实例化WebView对象 
        webview = new WebView(this); 
        //设置WebView属性,能够执行Javascript脚本 
        webview.getSettings().setJavaScriptEnabled(true); 
        //加载需要显示的网页 
        webview.loadUrl("http://www.51cto.com/"); 
        //设置Web视图 
        setContentView(webview); 
    } 
     
    @Override
    //设置回退 
    //覆盖Activity类的onKeyDown(int keyCoder,KeyEvent event)方法 
    public boolean onKeyDown(int keyCode, KeyEvent event) { 
        if ((keyCode == KeyEvent.KEYCODE_BACK) && webview.canGoBack()) { 
            webview.goBack(); //goBack()表示返回WebView的上一页面 
            return true; 
        } 
        return false; 
}
在AndroidManifest.xml文件中的17行添加权限
 <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.android.webview.activity"
      android:versionCode="1"
      android:versionName="1.0">
    <uses-sdk android:minSdkVersion="10" />
 
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".MainActivity"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
    <uses-permission android:name="android.permission.INTERNET"/>
</manifest>
效果图:

第二种方法的步骤:
1、在布局文件中声明WebView
2、在Activity中实例化WebView
3、调用WebView的loadUrl( )方法,设置WevView要显示的网页
4、为了让WebView能够响应超链接功能,调用setWebViewClient( )方法,设置  WebView视图
5、用WebView点链接看了很多页以后为了让WebView支持回退功能,需要覆盖覆盖Activity类的onKeyDown()方法,如果不做任何处理,点击系统回退剪键,整个浏览器会调用finish()而结束自身,而不是回退到上一页面
6、需要在AndroidManifest.xml文件中添加权限,否则出现Web page not available错误。
<uses-permission android:name="android.permission.INTERNET"/>
 下面是具体的例子:
MainActivity.java
package com.android.webview.activity; 
 
import android.app.Activity; 
import android.os.Bundle; 
import android.view.KeyEvent; 
import android.webkit.WebView; 
import android.webkit.WebViewClient; 
 
public class MainActivity extends Activity { 
    private WebView webview; 
    @Override
    public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.main); 
        webview = (WebView) findViewById(R.id.webview); 
        //设置WebView属性,能够执行Javascript脚本 
        webview.getSettings().setJavaScriptEnabled(true); 
        //加载需要显示的网页 
        webview.loadUrl("http://www.51cto.com/"); 
        //设置Web视图 
        webview.setWebViewClient(new HelloWebViewClient ()); 
    } 
     
    @Override
    //设置回退 
    //覆盖Activity类的onKeyDown(int keyCoder,KeyEvent event)方法 
    public boolean onKeyDown(int keyCode, KeyEvent event) { 
        if ((keyCode == KeyEvent.KEYCODE_BACK) && webview.canGoBack()) { 
            webview.goBack(); //goBack()表示返回WebView的上一页面 
            return true; 
        } 
        return false; 
    } 
     
    //Web视图 
    private class HelloWebViewClient extends WebViewClient { 
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) { 
            view.loadUrl(url); 
            return true; 
        } 
    } 
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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/webview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        />
</LinearLayout>
在AndroidManifest.xml文件中的17行添加权限
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.android.webview.activity"
      android:versionCode="1"
      android:versionName="1.0">
    <uses-sdk android:minSdkVersion="10" />
 
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".MainActivity"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
    <uses-permission android:name="android.permission.INTERNET"/>
</manifest>

Android手机中内置了一款高性能webkit内核浏览器,在SDK中封装为一个叫做WebView组件

WebView在开发过程中应该注意几点
    1.AndroidManifest.xml
中必须使用许可"android.permission.INTERNET",否则会出Webpage not available错误。
    2.
如果访问的页面中有Javascript,则webview必须设置支持Javascript

    WebSettings webSetting = webview.getSettings();
        webSetting.setJavaScriptEnabled(true); 

    3.
如果页面中链接,如果希望点击链接继续在当前browser中响应,而不是新开Android的系统browser中响应该链接,必须覆盖webviewWebViewClient对象。

 

1        mWebView.setWebViewClient(new WebViewClient(){      

2                publicboolean shouldOverrideUrlLoading(WebView view, String url) {      

3                                view.loadUrl(url);      

4                                returntrue;      

5                }      

6        });  

 4.如果不做任何处理,浏览网页,点击系统“Back”键,整个Browser会调用finish()而结束自身,如果希望浏览的网页回退而不是推出浏览器,需要在当前Activity中处理并消费掉该Back事件。

7        publicboolean onKeyDown(int
keyCode, KeyEventevent) {      

8                if((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) {      

9                    mWebView.goBack();      

10                        returntrue;      

11             }      

12             returnsuper.onKeyDown(keyCode,event);      

13         }

 5.如果webView中需要用户手动输入用户名、密码或其他,则webview必须设置支持获取手势焦点。

webview.requestFocusFromTouch();

 6.WebView 加载界面主要调用三个方法:LoadUrlLoadDataLoadDataWithBaseURL.
 1、LoadUrl            直接加载网页、图片并显示.(本地或是网络上的网页、图片、gif)
  2、LoadData           显示文字与图片内容(模拟器1.5、1.6)
  3、LoadDataWithBase  显示文字与图片内容(支持多个模拟器版本)

 

WebSettings的常用方法介绍

14       
setJavaScriptEnabled(true);

          //支持js脚步

15        setPluginsEnabled(true);

          //支持插件

16        setUseWideViewPort(false);

         //将图片调整到适合webview的大小

17        setSupportZoom(true);

         //支持缩放

18        setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);

            //支持内容从新布局

19        supportMultipleWindows();

        //多窗口

20        setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);

        //关闭webview中缓存

21        setAllowFileAccess(true);

        //设置可以访问文件

22        setNeedInitialFocus(true);

        //当webview调用requestFocus时为webview设置节点
     webSettings.setBuiltInZoomControls(true);

        //设置支持缩放

23        setJavaScriptCanOpenWindowsAutomatically(true);

           //支持通过JS打开新窗口

24        setLoadsImagesAutomatically(true);

           //支持自动加载图片

WebViewClient的方法全解

25     doUpdateVisitedHistory(WebViewview,Stringurl,
boolean isReload)

         (更新历史记录)

26     onFormResubmission(WebViewview,MessagedontResend,Messageresend)

         (应用程序重新请求网页数据)

27     onLoadResource(WebViewview,Stringurl)

            在加载页面资源时会调用,每一个资源(比如图片)的加载都会调用一次。

28     onPageStarted(WebViewview,Stringurl,Bitmapfavicon)

           这个事件就是开始载入页面调用的,通常我们可以在这设定一个loading的页面,告

        诉用户程序在等待网络响应。

29     onPageFinished(WebViewview,Stringurl)

           在页面加载结束时调用。同样道理,我们知道一个页面载入完成,于是我们可以关

       闭loading 条,切换程序动作。

30     onReceivedError(WebViewview,
int errorCode, Stringdescription,StringfailingUrl)

       (报告错误信息)

31     onReceivedHttpAuthRequest(WebViewview,HttpAuthHandlerhandler,Stringhost,

       Stringrealm)(获取返回信息授权请求)

32     onReceivedSslError(WebViewview,SslErrorHandlerhandler,SslErrorerror)

       重写此方法可以让webview处理https请求。

33     onScaleChanged(WebViewview,
float oldScale, float newScale)

        (WebView发生改变时调用)

34     onUnhandledKeyEvent(WebViewview,KeyEventevent)

      (Key事件未被加载时调用)

35     shouldOverrideKeyEvent(WebViewview,KeyEventevent)

       重写此方法才能够处理在浏览器中的按键事件。

36     shouldOverrideUrlLoading(WebViewview,Stringurl)

        在点击请求的是链接是才会调用,重写此方法返回true表明点击网页里面的链接还是在当前的webview里跳转,不跳到浏览器那边。这个函数我们可以做很多操作,比如我们读取到某些特殊的URL,于是就可以不打开地址,取消这个操作,进行预先定义的其他操作,这对一个程序是非常必要的。

原来是因为WebView默认没有开启文件下载的功能,如果要实现文件下载的功能,需要设置WebView的DownloadListener,通过实现自己的DownloadListener来实现文件的下载。具体操作如下:

    1、设置WebView的DownloadListener:

    webView.setDownloadListener(new MyWebViewDownLoadListener());

    2、实现MyWebViewDownLoadListener这个类,具体可以如下这样:    

[java] view
plain
copy

  1. private class MyWebViewDownLoadListener implements DownloadListener {  
  2.   
  3.         @Override  
  4.         public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype,  
  5.                                     long contentLength) {  
  6.             Uri uri = Uri.parse(url);  
  7.             Intent intent = new Intent(Intent.ACTION_VIEW, uri);  
  8.             startActivity(intent);  
  9.         }  
  10.   
  11.     }  

    这只是调用系统中已经内置的浏览器进行下载,还没有WebView本身进行的文件下载,不过,这也基本上满足我们的应用场景了。

1、添加上网权限:<uses-permission android:name="android.permission.INTERNET" />

2、设置webview

复制代码
 1 WebView webView;
 2 WebSettings ws;
 3 
 4 
 5 ws = webView.getSettings();
 6 ws.setAppCacheEnabled(true);// 设置启动缓存
 7 ws.setAppCacheMaxSize(1024 * 10);// 设置最大缓存
 8 ws.setSupportZoom(true);// 设置成拖动放大缩小
 9 ws.setBuiltInZoomControls(true);
10 ws.setCacheMode(WebSettings.LOAD_NO_CACHE);// 设置缓存模式
11 // 设置支持Javascript
12 webView.getSettings().setJavaScriptEnabled(true);
13 webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
14 
15 // 缓存,离线应用
16 webView.getSettings().setAppCacheEnabled(true);
17 webView.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);
18 webView.getSettings().setAppCacheMaxSize(1024 * 1024 * 8);
复制代码

3、获取网页对话框

复制代码
webView.setWebChromeClient(new WebChromeClient() {

@Override
public boolean onJsAlert(WebView view, String url, String message,
final JsResult result) {
// TODO Auto-generated method stub
// 构建一个Builder来显示网页中的对话框
Builder builder = new Builder(context);
builder.setTitle("警告");
builder.setMessage(message);
builder.setPositiveButton(android.R.string.ok,
new AlertDialog.OnClickListener() {
public void onClick(DialogInterface dialog,
int which) {
// 点击确定按钮之后,继续执行网页中的操作
result.confirm();
}
});
builder.setCancelable(false);
builder.create();
builder.show();
return true;
}

@Override
public boolean onJsConfirm(WebView view, String url,
String message, final JsResult result) {
// TODO Auto-generated method stub
Builder builder = new Builder(context);
builder.setTitle("confirm");
builder.setMessage(message);
builder.setPositiveButton(android.R.string.ok,
new AlertDialog.OnClickListener() {
public void onClick(DialogInterface dialog,
int which) {
result.confirm();
}
});
builder.setNegativeButton(android.R.string.cancel,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int which) {
result.cancel();
}
});
builder.setCancelable(false);
builder.create();
builder.show();
return true;
}

@Override
public void onProgressChanged(WebView view, int newProgress) {// 加载进度
// TODO Auto-generated method stub
super.onProgressChanged(view, newProgress);
}

});
复制代码

4、如果希望点击链接由自己处理,而不是新开Android的系统browser中响应该链接。

  给WebView添加一个事件监听对象(WebViewClient)

5、webview取得焦点

复制代码
webView.setOnTouchListener(new OnTouchListener() {

@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub

webView.requestFocus();
return false;
}
});
复制代码

6、提示加载对话框

pd=ProgressDialog.show(context, "请稍后", "正在加载中...");

  当网页加载完成后,调用pd.dismiss();

Settings是WebView提供给上层App的一个配置Webview的接口,每个WebView都有一个WebSettings,要控制WebView的行为,只能通过WebView.getSettings()获取WebSettings对象的引用,然后再改变它的属性。
Browser有一个BrowserSettings用来管理所有的配置信息,它是一个单键(Singleton)。BrowserSettings是直接管理WebSettings的,而UI部分则是由BrowserPreferencePage和Fragment来完成。BrowserSettings实现了OnSharedPreferenceChangedListener,当某个配置项发生变化时,BrowserSettings的接口onPreferencesChanged就会被回调到,然后BrowserSettings就会把配置通过WebSettings应用到WebView中,所以这些Settings都是及时生效的。
一共有三类Settings:共享Settings,静态Settings和动态Settings。静态就是不会在Browser运行时发生变化的,也就是说在Browser的Settings中无法改变的一些配置,这些跟应用程序内部关联较多,比如应用程序的数据存放地点等,而与用户层关系不多;共享Settings是独立于WebView的,也就是说它被系统内所有WebView共享的一些配置,比如Cookie,它不需要为每个WebView单独配置。动态Settings就是用于动态配置WebView的,比如字体,缩放,是否加载图片,是否启用JavaScript等等。
初始化
因为Browser可以有多个窗口,每一个窗口都会有一个WebView,也就是说Browser会管理多个WebView,所以BrowserSettings也要管理多个WebSettings,因为每一个配置的改变都要应用到所有的WebView中。为了能让BrowserSettings能够管理多个WebSettings,它必须持有对这些WebSettings的引用。Browser在创建WebView的时候会把WebView的配置WebSettings通过接口放到BrowserSettings中,BrowserSettings中有一个列表,用于持有对WebSettings的引用。具体的BrowserWebViewFactory中的initWebViewSettings()方法会在每次创建WebView后调用,它把WebView的WebSettings取出,做些必要的初始化,然后放到BrowserSettings中,BrowserSettings.startManagingSettings()会加载SharedPreference文件中的信息对此WebSettings进行初始化,然后放到mManagedSettings列表中。
配置变更
用户进入Settings界面,进行配置的更改,每当有配置发生变化BrowserSettings.onSharedPreferencesChanged()会被回调到,它就会做syncManagedSettings()的动作,把共享设置同步到底层去(也即把设置同步到Cookiemanager中),再遍历列表mManagedSettings,把mPref中的信息全部同步到每个WebSettings中,这样所有的WebView都会实时的响应配置变更。
设置的界面和BrowserSettings没有直接的关联,界面是通过PreferenceActivity和Fragment把各种Settings呈现给用户,而BrowserSettings是把配置信息同步给WebView也就是让配置生效。它们之间的信息桥梁是SharedPreference,也就是说PreferenceActivity和Fragment从用户处接收配置信息,然后放到SharedPreference中,BrowserSettin

Android WebView缓存

在项目中经常会使用到WebView控件,当加载html页面时,会在/data/data/应用package目录下生成database与cache两个文件夹如下图如示:

请求的url记录是保存在webviewCache.db,而url的内容是保存在webviewCache文件夹下.

         

为了便于理解,接下来模拟一个案例,定义一个html文件,在里面显示一张图片,用WebView加载出来,然后再试着从缓存里把这张图片读取出来并显示。

      

第一步:新建一个Android工程命名为WebViewCache.目录结构如下:

     

第二步:在assets目录下新建一个html文件,命名为index.html

复制代码
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>WebViewCacheDemo</title>

<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<

抱歉!评论已关闭.