webview详解

webview详解

1. 简介

WebView是一个基于webkit引擎、展现web页面的控件。

android的Webview在低版本和高版本采用了不同的webkit版本内核,4.4后直接使用了Chrome。


2. 作用

  • 显示和渲染Web页面
  • 直接使用html文件(网络上或本地assets中)作布局
  • 可和JavaScript交互调用

WebView控件功能强大,除了具有一般View的属性和设置外,还可以对url请求、页面加载、渲染、页面交互进行强大的处理。


3. 使用介绍

一般来说Webview可单独使用,可联合其子类一起使用,所以接下来,我会介绍:

  • Webview自身的常见方法;
  • Webview的最常用的子类 
    (WebSettings类、WebViewClient类、WebChromeClient类)
  • Android和Js的交互

3.1 Webview常用方法

3.1.1 WebView的状态

webView.onResume();/**WebView为活跃状态,能正常执行网页的响应
webView.onPause//通过onPause动作通知内核暂停所有的动作,比如DOM的解析、plugin的执行、JavaScript执行。

//销毁Webview

/在关闭了Activity时,如果Webview的音乐或视频,还在播放。就必须销毁Webview //但是注意:webview调用destory时,webview仍绑定在Activity上 //这是由于自定义webview构建时传入了该Activity的context对象 //因此需要先从父容器中移除webview,然后再销毁webview:


@Override protected void onDestroy() { 
if (webView != null) {
 webView.loadDataWithBaseURL(null, "", "text/html", "utf-8", null); 
 webView.clearHistory(); 
 webView.clearCache(true);  
((ViewGroup) webView.getParent()).removeView(webView);
  webView.destroy();  
 webView = null; 
 removeCookies(mcontext); 
 }
 super.onDestroy(); 
 }

3.1.2 关于前进 / 后退网页

//是否可以后退


Webview.canGoBack()

//后退网页

Webview.goBack()

//是否可以前进

Webview.canGoForward()

//前进网页

Webview.goForward() //以当前的index为起始点前进或者后退到历史记录中指定的steps //如果steps为负数则为后退,正数则为前进 Webview.goBackOrForward(intsteps)

实际应用

1.返回键中的应用


// 问题:在不做任何处理前提下 ,浏览网页时点击系统的“Back”键,整个 Browser 会调用 finish()而结束自身 // 目标:点击返回后,是网页回退而不是推出浏览器 // 解决方案:在当前Activity中处理并消费掉该 Back 事件
 public boolean onKeyDown(int keyCode, KeyEvent event) {
 if ((keyCode == KEYCODE_BACK) && webView.canGoBack()) {
 webView.goBack(); 
 return true;  
return super.onKeyDown(keyCode, event); }
2.返回按钮中的应用




h5_back.setOnClickListener(new View.OnClickListener() {
 @Override  public void onClick(View v) {
 if (webView.canGoBack()) { 
 webView.goBack(); 
 } else {
            finish();  }
    }
});

3.1.3 清除缓存数据

/清除网页访问留下的缓存

//由于内核缓存是全局的因此这个方法不仅仅针对webview而是针对整个应用程序.

Webview.clearCache(true);

//清除当前webview访问的历史记录 //只会webview访问历史记录里的所有记录除了当前访问记录

Webview.clearHistory();

//这个api仅仅清除自动完成填充的表单数据,并不会清除WebView存储到本地的数据 Webview.clearFormData();

应用一般在页面销毁的时候调用


3.2 常用类

3.2.1 WebSettings类

  • 作用:对WebView进行配置和管理
  • 配置步骤 & 常见方法:

配置步骤1:添加访问网络权限(AndroidManifest.xml)

这是前提!这是前提!这是前提!

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

配置步骤2:生成一个WebView组件(有两种方式)

//方式1:直接在在Activity中生成 WebView webView = new WebView(this
//方法2:在Activity的layout文件里添加webview控件: WebView webview = (WebView) findViewById(R.id.webView1);

配置步骤3:进行配置-利用WebSettings子类(常见方法)】

/声明WebSettings子类


WebSettings webSettings = webView.getSettings();

//如果访问的页面中要与Javascript交互,则webview必须设置支持Javascript

webSettings.setJavaScriptEnabled(true);

//支持插件

webSettings.setPluginsEnabled(true);

//设置自适应屏幕,两者合用

webSettings.setUseWideViewPort(true);

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

webSettings.setLoadWithOverviewMode(true);

// 缩放至屏幕的大小 //缩放操作

webSettings.setSupportZoom(true);

//支持缩放,默认为true。是下面那个的前提。

webSettings.setBuiltInZoomControls(true);

//设置内置的缩放控件。若为false,则该WebView不可缩放

webSettings.setDisplayZoomControls(false);

//隐藏原生的缩放控件 //其他细节操作

webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);/、关闭webview中缓存

webSettings.setAllowFileAccess(true); //设置可以访问文件

webSettings.setJavaScriptCanOpenWindowsAutomatically(true); //支持通过JS打开新窗口

webSettings.setLoadsImagesAutomatically(true); //支持自动加载图片

webSettings.setDefaultTextEncodingName("utf-8");//设置编码格式


常见用法:设置WebView缓存


//优先使用缓存: // 
webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);  
//缓存模式如下: 
 //LOAD_CACHE_ONLY: 不使用网络,只读取本地缓存数据  
//LOAD_DEFAULT: (默认)根据cache-control决定是否从网络上取数据。
 //LOAD_NO_CACHE: //不使用缓存,只从网络获取数据. 
 //LOAD_CACHE_ELSE_NETWORK,只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。 
 //不使用缓存: //        webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);

3.2.2 WebViewClient类

  • 作用:处理各种通知 & 请求事件
  • 常见方法:

常见方法1:shouldOverrideUrlLoading()

  • 作用:打开网页时不调用系统浏览器, 而是在本WebView中显示;在网页上的所有加载都经过这个方法,这个函数我们可以做很多操作。
//步骤2. 选择加载方式 //方式1. 加载一个网页: webView.loadUrl("http://www.google.com/");


//方式2:加载apk包中的html页面 webView.loadUrl("file:///android_asset/test.html");

//方式3:加载手机本地的html页面 webView.loadUrl("content://com.android.htmlfileprovider/sdcard/test.html");

//步骤3. 复写shouldOverrideUrlLoading()方法,使得打开网页时不调用系统浏览器, 而是在本WebView中显示

webView.setWebViewClient(new WebViewClient(){

@Override public boolean shouldOverrideUrlLoading(WebView view, String url)

{ view.loadUrl(url);

return true; } });

或许你想要跳转到自定义的链接调到原生页面

你可以这样写:


  @Override  public boolean shouldOverrideUrlLoading(WebView view, String url) { 
//            lppz://store.m.lppz.local/click/functionId=toProductDetail?productId=11000221 
 try { if (url != null) { if (url.indexOf("m.lppz.local") > 0) {
                        String webUrl = URLDecoder.decode(url, "UTF-8").split("//")[1]; 
 JumpUtils.jumpPage(WebView_JSActivity.this, webUrl, "");  //你想要跳转的界面
 return true;  }
                 else { return false;  }
                }
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();  
 return false;  }
常见方法2:onPageStarted()
  • 作用:开始载入页面调用的,我们可以设定一个loading的页面,告诉用户程序在等待网络响应。
 @Override 
 public void onPageStarted(WebView view, String url) { 
 super.onPagestarted(view, url); 
              }

常见方法3:onPageFinished()


  • 作用:在页面加载结束时调用。我们可以关闭loading 条,切换程序动作。
 @Override 
 public void onPageFinshed(WebView view, String url) { 
 super.onPageFinished(view, url); 
     }


常见方法5:onReceivedError()

作用:加载页面的服务器出现错误时(如404)调用。


@Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl)
 { isLoadError = true;  
 if (isLoadError) { layoutEmpty.setVisibility(View.VISIBLE); 
 } else {
       layoutEmpty.setVisibility(View.GONE); 
 }
}



3.2.3 WebChromeClient类

  • 作用:辅助 WebView 处理 Javascript 的对话框,网站图标,网站标题等等。
  • 常见使用:

常见方法1: onProgressChanged()

  • 作用:获得网页的加载进度并显示
webview.setWebChromeClient(new WebChromeClient(){ @Override public void onProgressChanged(WebView view, int newProgress) { if (newProgress < 100) {
 if (newProgress == 100) { 
 pg1.setVisibility(View.GONE);//加载完网页进度条消失
 } else {
       h5_top_rl.setVisibility(View.VISIBLE); 
 h5_title.setText("加载中......"); 
 pg1.setVisibility(View.VISIBLE);//开始加载网页时显示进度条 
 pg1.setProgress(newProgress);//设置进度值 }
})

常见方法2: onReceivedTitle()

  • 作用:获取Web页中的标题 
    每个网页的页面都有一个标题,比如www.baidu.com这个页面的标题即“百度一下,你就知道”,那么如何知道当前webview正在加载的页面的title并进行设置呢?
webview.setWebChromeClient(new WebChromeClient(){ @Override public void onReceivedTitle(WebView view, String title) {
       titleview.setText(title);
    }
通过内嵌页的编写,发现一个问题, onReceivedTitle()方法只能获取标题,在退回页面的时候标题并没有变


通过测试发现在

 @Override 
 public void onPageFinshed(WebView view, String url) { 
 super.onPageFinished(view, url); 
     }


方法同样可以获取到title,view,getTitle();回退时页面也随之改变




4 cookie的应用

由于需要和js交互的问题,js端需要存cookie,防止切换账号时,商城页面需要登录的位置失效


所以在webview端需要设置接收cookie



    //开启cookies  public void synCookies(Context context, String url) {
        CookieSyncManager.createInstance(context); 
 CookieManager  cookieManager = CookieManager.getInstance(); 
 cookieManager.setAcceptCookie(true); //        cookieManager.removeSessionCookie();//移除 //        cookieManager.setCookie(url, cookies);//cookies是在HttpClient中获得的cookie 
 CookieSyncManager.getInstance().sync();
  }
需要注意的是:在webView,loadUrl()之前调用;在设置cookie之后 WebSettings设置参数无效


开启了cookie就要清除掉cookie

在页面销毁的时候调用,或者在退出登录的时候调用

调用方法如下:

    //移除ookies  public void removeCookies(Context context) {
        CookieSyncManager.createInstance(context);
  CookieManager cookieManager = CookieManager.getInstance();
//        cookieManager.removeSessionCookie(); // 
 cookieManager.removeExpiredCookie(); 
 cookieManager.removeAllCookie();  
 CookieSyncManager.getInstance().sync();//这句必调,不然失效
  }



后面持续更新........