Android WebView使用,Http/Https,硬件加速等相关细节详解

概述

在应用的开发过程中,经常遇到需要经常变化的页面,一般针对这种页面,我们会用WebView来实现.如隐私条款等等.并且随着 hybrid 的兴起,webview 将会更加常用.

loadDataWithBaseURL 与 loadData

loadData

//方法原型
loadData(String data, String mimeType, String encoding)

loadData 用于加载一段html文本,这个和loadUrl是有区别的,
loadUrl 是根据一个url来加载一个网页,他们各有利弊,
参考:WebView到底该使用loadUrl还是loadData

其中loadData 使用 #、%、\、? 四种字符易出现问题.

% 会报找不到页面错误,页面全是乱码。乱码样式见符件。
# 会让你的goBack失效,但canGoBack是可以使用的。于是就会产生返回按钮生效,但不能返回的情况。
\ 会被当做转义字符.

如果出现乱码问题,需要将encoding参数设置为utf-8.
mimeType,指定mineType类型,如text/html; charset=utf-8

loadDataWithBaseURL

//方法原型
 public void loadDataWithBaseURL(String baseUrl, String data,
            String mimeType, String encoding, String failUrl) {
    }
public void loadData(String data, String mimeType, String encoding) {
    }
public void loadUrl(String url) {
    } 
 public void loadUrl(String url,Map<Stirng,String> extraHeaders) {
    }   

loadDataWithBaseURL可以指定相对根路径,也可以指定历史Url

baseUrl相对根路径,常见于WebView中的超链接或者是image元素,如使用绝对路径传""即可。

比如, 我们的data格式:

String body ="示例:这里有个img标签,地址是相对路径<img src='/uploads/allimg/130923/1FP02V7-0.png' />";

如果baseUrl没有指定为网站域名,那么这张图片将显示不出来。

常用属性

通过mWebView.getSettings()拿到WebView的设置.

mWebView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);//支持通过JS打开新窗口
mWebView.getSettings().setSupportZoom(true);//设置是否支持缩放
mWebView.getSettings().setBuiltInZoomControls(true);//设置是否显示缩放工具
webview.getSettings().setDisplayZoomControls(false);//设定缩放控件隐藏
/**http://stackoverflow.com/questions/5448841/what-do-setusewideviewport-and-setloadwithoverviewmode-precisely-do*/
webview.getSettings().setLoadWithOverviewMode(true);// loads the WebView completely zoomed out
webview.getSettings().setUseWideViewPort(true); //makes the Webview have a normal viewport (such as a normal desktop browser), while when false the webview will have a viewport constrained to its own dimensions (so if the webview is 50px*50px the viewport will be the same size)
webview.getSettings().setAllowFileAccess(true); // 允许访问文件  


mWebView.getSettings().setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);//一般很少会用到这个,用WebView组件显示普通网页时一般会出现横向滚动条,这样会导致页面查看起来非常不方便。//LayoutAlgorithm是一个枚举,用来控制html的布局,总共有三种类型://NORMAL:正常显示,没有渲染变化。//SINGLE_COLUMN:把所有内容放到WebView组件等宽的一列中。//NARROW_COLUMNS:可能的话,使所有列的宽度不超过屏幕宽度。
mWebView.getSettings().setDefaultFontSize(18);//设置默认的字体大小,默认为16,有效值区间在1-72之间。
//若要考虑兼容3.0以下版本则:
/**http://jingyan.baidu.com/article/48b37f8d0b918e1a646488ec.html*/
if(android.os.Build.VERSION.SDK_INT>=11){
    this.getSettings().setDisplayZoomControls(false);
}else{
    this.setZoomControlHide(this); 
}

//Android 3.0(11) 以下使用以下方法:
//利用java的反射机制
public void setZoomControlHide(View view) {
        try {  
            Class webview = Class.forName("android.webkit.WebView");  
            Method method = webview.getMethod("getZoomButtonsController");  
            zoomController = (ZoomButtonsController) method.invoke(this, null);  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
}  

更多设置参考:www.cnblogs.com/zgz345/p/3768174.html

-WebView 链接在WebView内部打开,而非调用系统浏览器的方法.

重写shouldOverrideUrlLoading,并且return true;

WebViewClient与WebChromeClient

WebViewClient主要帮助WebView处理各种通知、请求事件的,比如:

onLoadResource
onPageStart
onPageFinish
onReceiveError //错误,可以在此显示一个错误页面
onReceivedHttpAuthRequest

WebChromeClient主要辅助WebView处理Javascript的对话框、网站图标、网站title、加载进度等,比如:

onCloseWindow//关闭WebView
onCreateWindow()
onJsAlert //WebView上alert无效,需要定制WebChromeClient处理弹出
onJsPrompt
onJsConfirm
onProgressChanged
onReceivedIcon
onReceivedTitle//获取title

如果你的WebView只是用来处理一些v的页面内容,只用WebViewClient就行了,如果需要更丰富的处理效果,比如JS、进度条等,就要用到WebChromeClient

比如,我们想要在webview 中相应Email,telIntent,我们继承WebViewClient 并重写shouldOverrideUrlLoading 方法

public abstract class WebClient extends android.webkit.WebViewClient {
  private final WeakReference<Context> contextWeakReference;

  public WebClient(Context context) {
    contextWeakReference = new WeakReference<>(context);
  }

  @Override public boolean shouldOverrideUrlLoading(WebView view, String url) {
    if (url.startsWith("mailto:") || url.startsWith("geo:") || url.startsWith("tel:")) {
      final Context context = contextWeakReference.get();
      if (context != null) {
        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
        context.startActivity(intent);
        view.reload();
      }
    } else {
      reloadUrl(view, url);
    }

    return true;
  }

  public abstract void reloadUrl(WebView view, String url);
}

onPageFinished:

onReceivedTitle()方法在goback()之后无效。

这时,我们可以使用onPageFinished(WebView view, String url)方法来实现返回及时刷新标题

 WebView mWebView = (WebView) findViewById(R.id.mwebview);
    mWebView.setWebViewClient(new WebViewClient() { 
        @Override 
        public void onPageFinished(WebView view, String url) {
            setTitle(view.getTitle());
        } 
    }); 

处理https请求

android 默认是不处理https请求的,请求https会显示空白。


webView.setWebViewClient(new WebViewClient() {  

        @Override  
        public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {  
            handler.proceed();  
            //default
//            handler.cancel();  
//            handler.handleMessage(null);  
        }  
    });  

cookies 和历史纪录

比如在某些场景中,我们的用户在客户端 登录了,要在 网页中也保持登录状态,则可以使用cookies 来实现,不过需要服务器端配合完成.

//cookies清理
CookieSyncManager.createInstance(this); 
CookieSyncManager.getInstance().startSync(); 
CookieManager.getInstance().removeSessionCookie(); 

//清理cache 和历史记录
webView.clearCache(true); 
webView.clearHistory();

文件下载

我们都知道WebView中 有这么一个方法

// 方法原型
public void setDownloadListener(DownloadListener listener){}

那么我们只需要自定义一个DownloadListener 即可

public class WebViewDownLoadListener implements DownloadListener {
  @Override public void onDownloadStart(String url, String userAgent, String contentDisposition,
      String mimetype, long contentLength) {
      // 参数含义: url :文件现在链接
      // userAgent : 用户浏览器代理
      // contentDisposition : 文件描述符
      // mimetype : 文件的类型
      // contentLength : 文件的长度
  }
}

硬件加速

Android自带的WebView非常的鸡肋,比如不能打开pdf,播放视屏也只能打开硬件加速才能支持,但是这里也存在着 问题,比如,在某些机型上会崩溃

详见:Android硬件加速的一些问题和错误

这里的做法是在 onPageStart中关闭硬件加速,在onPageFinish中开启硬件加速

HTTP/HTTPS混合

在应用全面适配https后发现 某些图片不再显示了,通过抓包工具发现,是 Https 页面中包含了 Http的 图片链接。使用混合模式即可。

//http,https 混合使用
    // http://developer.android.com/reference/android/webkit/WebSettings.html#setMixedContentMode(int)
    if (Build.VERSION.SDK_INT >= 21) {
      webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
    }

相关源码:WebViewUtil

参考:泡在网上的日子
Android WebView中获取网页的title (包括调用goback)
WebView到底该使用loadUrl还是loadData

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值