继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

Webview 开发要点

潇湘沐
关注TA
已关注
手记 104
粉丝 12
获赞 38

随着 Android 系统的迭代改进,用户体验得到很大改善,开发难度也相对降低不少。

但由于开发成本和不够灵活(除了插件化技术和动态补丁技术以外,新功能都需要发版),

因而原生网页在现在的 Android Product 依然占有一定的位置,甚至出现了一些例如 Hybrid 框架。

Android Sytem 本身也提供了对原生网页的支持控件,这就是今天的主角 WebView。


尽管是官方提供的控件,WebView 的使用依然是坑无数,想要获得一个较好的用户体验更是难上加难。

在接下来的文章中,将详细说一下个人总结出了的一些经验,能够对大家的开发带来一些好处,就更高兴了。

webview 基础设置

如果只是想单纯地显示一个静态页面,那么调用 WebView 的 loadUrl 即可,然而这只是刚起步。

下面是干活,如何正确地配置WebView 的 settings,这些都是实际经过项目验证的,可放心使用

JS 支持 webview.getSettings().setJavaScriptEnabled(true); 网页的交互是依赖于 JS 的,通过这个开关,可以正确地开启 H5 网页的交互功能。在使用的时候,可能 lint 会提示警告。开

启这个功能后,会引入跨域攻击的隐患。

如果确信不会引入问题的话,可以加入 @SuppressLint(“SetJavaScriptEnabled”) 来避免编译器的提示.

自适应屏幕 严格来讲,对手机屏幕适配是原生网页 CSS 和 JS 的工作,但往往现实很骨感,WebView 也需要对 PC 等宽的网页进行小的视频,不至于显示一塌糊涂。 webSettings.setUseWideViewPort(true); webSettings.setLoadWithOverviewMode(true); 通过设置这两个值,能够保证对 PC 等宽的页面也能良好显示。

缓存策略 webview.getSettings().setCacheMode(int model); model 可指定 Default、NORMAL(被弃用)、CACHE_ELSE_NETWORK(优先使用Cache,即使根据TTL 和 Soft TTL Cache已经过期)、LOAD_NO_CACHE(不弃用缓存)、LOAD_CACHE_ONLY(只用Cache,网络都不请求了)。 建议在实际开发的时候,使用LOAD_NO_CACHE,来避免一些缓存相关的bug。

BASE64 图片显示 可能大家没有注意点到,没有 Page 的图片在页面上无法显示,这是怎么回事?这些图片本身不是URL,而是通过 base 64 编码后产生的图片。在 5.0 以后,Webview 默认禁止了存在潜在隐患的功能,但这也导致在 5.0 系统上,无法显示Base64 的图片。在5.0 之后系统上,开启 webview.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW); 即可解决问题。。


webview JS与本地交互


这部分内容就比较复杂了,篇幅缘故不做过多展开,有需求的可以看这个文档。https://www.cigital.com/blog/android-webviews-and-the-javascript-to-java-bridge/


在代码中注入的方式如下:webview.addJavascriptInterface(jsPlugin, PLUGIN);


webview 播放视频


可能大家在开始的时候,和我一样认为在Webview中播放视频是非常容易,几乎是不需要客户端做处理的。播放视频是容易,想要处理好细节就很难。大家可以试试在播放一个视频之后,返回上一个界面或者回到主界面的时候,你会神奇地发现居然还有声音在播放!


原因就是 WebView threads never stop!


解决方法也很简单,在相应的生命周期中,对 WebView 进行相关的处理。由于 WebView 本身占用着 plugins、 DOM 等资源,当它离开屏幕的时候,也应该释放其占有的 CPU 、网络资源。


[代码]java代码:


private void destroyWebView() {

if (webview != null) {

webview.removeAllViews();

webview.destroy();

webview = null;

}

}


private void pauseWebView() {

if (webview == null) {

return;

}

webview.onPause();

}


private void resumeWebView() {

if (webview == null) {

return;

}

webview.onResume();

}



webview 支持网页回滚


在支持 JS 过后,就可以在网页端实现往后倒退的功能,我们知道正常情况下按下返回键是触发 Activity 的回退操作,根本轮不到 Webview 来响应。


因而实现这个功能首要前提就是,链接系统的返回事件,先判断网页是否可回滚,如果可以回滚,那么就拦截掉返回事件。


判断方法也很简单:WebView.canGoBack()


最后问题来了,webview 提供了 goBack 方法,但这种方法有一些问题。初始页面为A,点击某个链接跳转到B,B页面重定向到C页面。


当调用webview.goBack()时,页面回退到B,然后接着会重定向回C页面。


解决这个问题,有一种方法是依赖于 JS,通过 JS 的 API 可以实现对历史记录的管控。


[代码]java代码:


webview.loadUrl("javascript:window.history.back();");



WebViewClient 与 WebChromeClient


设计到网络的应用就免不了要和各种事件、异常情况打交道,WebViewClient 和 WebChromeClient 则是 WebView 提供给我们的回调程序,便于我们处理各种情况。


一般来说,WebViewClient 是负责处理网页相关的事件和异常,几个重要的回调接口在于


onPageFinished

onReceivedError

onPageStarted

onReceivedSslError (在这里可以忽略一些证书引起的错误,强制执行)

而 WebChromeClient 则是负责一些 JS 加载和进度相关的东西,几个重要的回调是


getVideoLoadingProgressView

onReceivedTitle

getDefaultVideoPoster (视频加载时的默认图)

onProgressChanged (加载进度回调)

强大的调试工具


好东西总是留在最后,做个 web 开发的人都知道 Chrome 提供了强大的 Debug 工具,能够让我们比较方便地进行调试。那么有可能,对于 WebView 界面也能有用这么强大的调试功能吗? 答案是肯定以及肯定的。



if (BuildConfig.DEBUG && Build.VERSION.SDK_INT

>= Build.VERSION_CODES.KITKAT) {

   WebView.setWebContentsDebuggingEnabled(true);

}



在 API 19以后,Webview 就可以支持内容调试,方法很简单。

原文链接:http://www.apkbus.com/blog-705730-61741.html

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP