Android Webview + h5 通用调研

来源:互联网 发布:淘宝客服如何做到秒回 编辑:程序博客网 时间:2024/05/21 14:08

为什么要学习Android与H5互调?

微信,QQ空间等大量软件都内嵌了H5,不得不说是一种趋势。Android与H5互调可以让我们的实现混合开发,至于混合开发就是在一个App中内嵌一个轻量级的浏览器,一部分原生的功能改为Html 5来开发。
优势:使用H5实现的功能能够在不升级App的情况下动态更新,而且可以在Android或iOS的App上同时运行,节约了成本,提高了开发效率。
原理:其实就是Java代码和JavaScript之间的调用。
WebView简介

要实现Android与H5互调,WebView是一个很重要的控件,WebView可以很好地帮助我们展示html页面,所以有必要先了解一下WebView。

一丶WebView常用方法

(1)loadUrl

加载界面,其次还有LoadData和LoadDataWithBase方法

//加载assets目录下的test.html文件webView.loadUrl("file:///android_asset/test.html");//加载网络资源(注意要加上网络权限)webView.loadUrl("http://blog.csdn.net");

setWebViewClient(如果用户设置了WebViewClient,则在点击新的链接以后就不会跳转到系统浏览器了,而是在本WebView中显示。注意:并不需要覆盖 shouldOverrideUrlLoading 方法,同样可以实现所有的链接都在 WebView 中打开。)

WebViewClient主要用来辅助WebView处理各种通知、请求等事件,通过setWebViewClient方法设置。以下是它的几种常见用法:

实现对网页中超链接的拦截(比如如果是极客导航的主页,则直接拦截转到百度主页):
当点击页面中的链接后,会在WebView加载URL前回调shouldOverrideUrlLoading(WebView view, String url)方法,一般点击一个链接此方法调用一次。

 webView.setWebViewClient(new WebViewClient(){@Overridepublic boolean shouldOverrideUrlLoading(WebView view, String url) {    if("http://www.jikedaohang.com/".equals(url))                   {        view.loadUrl("https://www.baidu.com/");    }                return true;            }        });

(2)加载网页时替换某个资源(比如在加载一个网页时,需要加载一个logo图片,而我们想要替换这个logo图片,用我们assets目录下的一张图片替代)
我们知道我们在加载一个网页的同时也会加载js,css,图片等资源,所以会多次调用shouldInterceptRequest方法,我们可以在shouldInterceptRequest中进行图片替换。
注意:shouldInterceptRequest有两个重载:
①public WebResourceResponse shouldInterceptRequest (WebView view, String url) 【已过时】
②public WebResourceResponse shouldInterceptRequest (WebView view, WebResourceRequest request)
这两种方法主要是第二个参数的不同,WebResourceRequest 将能够获取更多的信息,提供了getUrl(),getMethod,getRequestHeaders等方法。这里主要是为了展示效果,使用了第一种回调方法。实现方法如下:

mWebView.setWebViewClient(new WebViewClient(){            @Override            public WebResourceResponse shouldInterceptRequest(WebView view, String url) {                WebResourceResponse response = null;                if (url.contains("logo")) {                    try {                        InputStream logo = getAssets().open("logo.png");                        response = new WebResourceResponse("image/png", "UTF-8", logo);                    } catch (IOException e) {                        e.printStackTrace();                    }                }                return response;            }        });

(3)设置开始加载网页、加载完成、加载错误时处理

webView.setWebViewClient(new WebViewClient() {        @Override      public void onPageStarted(WebView view, String url, Bitmap favicon) {          super.onPageStarted(view, url, favicon);          // 开始加载网页时处理 如:显示"加载提示" 的加载对话框          ...    }      @Override      public void onPageFinished(WebView view, String url) {          super.onPageFinished(view, url);          // 网页加载完成时处理  如:让 加载对话框 消失          ...    }      @Override      public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {          super.onReceivedError(view, errorCode, description, failingUrl);          // 加载网页失败时处理 如:提示失败,或显示新的界面        ...    }    }); 

(4)处理https请求,为WebView处理ssl证书设置WebView默认是不处理https请求的,需要在WebViewClient子类中重写父类的onReceivedSslError函数

webView.setWebViewClient(new WebViewClient() {        @Override      public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {          handler.proceed();  // 接受信任所有网站的证书          // handler.cancel();   // 默认操作 不处理          // handler.handleMessage(null);  // 可做其他处理      }   }); 

setWebChromeClient

WebChromeClient主要用来辅助WebView处理Javascript的对话框、网站图标、网站标题以及网页加载进度等。通过WebView的setWebChromeClient()方法设置。

(1)显示页面加载进度在WebChromeClient子类中重写父类的onProgressChanged函数,progress表示当前页面加载的进度,为1至100的整数

webView.setWebChromeClient(new WebChromeClient() {        public void onProgressChanged(WebView view, int progress) {            setTitle("页面加载中,请稍候..." + progress + "%");            setProgress(progress * 100);            if (progress == 100) {                //...         }        }    });  

(2)加快HTML网页加载完成速度(默认情况html代码下载到WebView后,webkit开始解析网页各个节点,发现有外部样式文件或者外部脚本文件时,会异步发起网络请求下载文件,但如果在这之前也有解析到image节点,那势必也会发起网络请求下载相应的图片。在网络情况较差的情况下,过多的网络请求就会造成带宽紧张,影响到css或js文件加载完成的时间,造成页面空白loading过久。解决的方法就是告诉WebView先不要自动加载图片,等页面finish后再发起图片加载。)

//1.首先在WebView初始化时添加如下代码if(Build.VERSION.SDK_INT >= 19) {  /*对系统API在19以上的版本作了兼容。因为4.4以上系统在onPageFinished时再恢复图片加载时,如果存在多张图片引用的是相同的src时,会只有一个image标签得到加载,因而对于这样的系统我们就先直接加载。*/        webView.getSettings().setLoadsImagesAutomatically(true);      } else {          webView.getSettings().setLoadsImagesAutomatically(false);      }  //2.在WebView的WebViewClient子类中重写onPageFinished()方法添加如下代码:  @Override  public void onPageFinished(WebView view, String url) {      if(!webView.getSettings().getLoadsImagesAutomatically()) {          webView.getSettings().setLoadsImagesAutomatically(true);      }  } 

setDownloadListener

通常webview渲染的界面中含有可以下载文件的链接,点击该链接后,应该开始执行下载的操作并保存文件到本地中。

创建DownloadListener

class MyDownLoadListener implements DownloadListener{      @Override      public void onDownloadStart(String url, String userAgent,String contentDisposition, String mimetype, long contentLength) {          //下载任务...,主要有两种方式          //(1)自定义下载任务          //(2)调用系统的download的模块          Uri uri = Uri.parse(url);          Intent intent = new Intent(Intent.ACTION_VIEW, uri);          startActivity(intent);      }

给webview加入监听

webview.setDownloadListener(new MyDownLoadListener());

(3)goBack()

返回上一浏览页面,通过重写onKeyDown方法实现点击返回键返回上一浏览页面而非退出程序

public boolean onKeyDown(int keyCode, KeyEvent event) {  //其中webView.canGoBack()在webView含有一个可后退的浏览记录时返回true        if ((keyCode == KeyEvent.KEYCODE_BACK) && webView.canGoBack()) {                   webView.goBack();                   return true;               }               return super.onKeyDown(keyCode, event);           }}

二丶WebSettings配置

  1. 获取WebSettings对象 WebSettings webSettings = webView.getSettings();
  2. 常用设置方法
    (1)支持js settings.setJavaScriptEnabled(true);
    (2)设置缓存方式,主要有以下几种:
    LOAD_CACHE_ONLY: 不使用网络,只读取本地缓存数据。
    LOAD_DEFAULT: 根据cache-control决定是否从网络上取数据。
    LOAD_CACHE_NORMAL: API level 17中已经废弃, 从API level 11开始作用同LOAD_DEFAULT模式。
    LOAD_NO_CACHE: 不使用缓存,只从网络获取数据。
    LOAD_CACHE_ELSE_NETWORK:只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。
    settings.setCacheMode(WebSettings.LOAD_NO_CACHE);
    (3)开启DOM storage API功能(HTML5 提供的一种标准的接口,主要将键值对存储在本地,在页面加载完毕后可以通过 JavaScript 来操作这些数据。)
    settings.setDomStorageEnabled(true);
    (4)设置数据库缓存路径settings.setDatabasePath(cacheDirPath);
    (5)设置Application Caches缓存目录
    settings.setAppCachePath(cacheDirPath);
    (6)设置默认编码settings.setDefaultTextEncodingName(“utf-8”);
    (7)将图片调整到适合webview的大小
    settings.setUseWideViewPort(false);
    (8)支持缩放settings.setSupportZoom(true);
    (9)支持内容重新布局
    settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
    (10)多窗口settings.supportMultipleWindows();
    (11)设置可以访问文件settings.setAllowFileAccess(true);
    (12)当webview调用requestFocus时为webview设置节点settings.setNeedInitialFocus(true);
    (13)设置支持缩放settings.setBuiltInZoomControls(true);
    (14)支持通过JS打开新窗口settings.setJavaScriptCanOpenWindowsAutomatically(true);
    (15)缩放至屏幕的大小settings.setLoadWithOverviewMode(true);
    (16)支持自动加载图片settings.setLoadsImagesAutomatically(true);
    三丶WebViewClient 的回调方法列表

学习资源:http://blog.csdn.net/qq_24530405/article/details/52067474

0 0