目录
引子
准备
区分APP和浏览器
配置WebView基础参数
WebViewClient对象
监听页面加载情况(开始加载、资源加载、完成加载、页面错误)
拦截页面链接
替换加载内容
WebChromeClient对象
替换Alert对话框
全屏播放视频
Cookie
如何同步登录状态
Web端与Native端互相通讯
WebView调用web端JS方法
web端调用native代码
早期API提供的方法:
自定义scheme
利用WebChromeClient.onJsPrompt
其他技巧
屏蔽长按事件
隐藏选择框
缩放按钮引起的崩溃
首页 数据库 mysql教程 WebView实用功能与技巧

WebView实用功能与技巧

May 28, 2018 am 10:06 AM
native web webview 功能 实用 技巧

引子 web?native?这是个争论了很久的问题。 自从微信开放了更多的JS接口之后,移动web开发重新火了起来,前端程序猿也水涨船高。 毫无疑问,web页面有诸多优点: 跨平台:一次开发,可以同时在Android,iOS和Other Phone上运行(美好的愿望) 快速迭代,内容

引子

web?native?这是个争论了很久的问题。
自从微信开放了更多的JS接口之后,移动web开发重新火了起来,前端程序猿也水涨船高。

毫无疑问,web页面有诸多优点:

  • 跨平台:一次开发,可以同时在Android,iOS和Other Phone上运行(美好的愿望)

  • 快速迭代,内容统一:内容修改后,不同版本都能展示最新内容。可以避免频繁的客户端升级,也无需经过App Store的审核

  • 语言优势:庞大JavaScript开发人员,能够带来移动端内容的繁荣

本人多年开发研究web与native混合APP,因为这里面有很多的坑,很有必要把经验归纳一番。

准备

区分APP和浏览器

我们的web页面是通过哪个应用打开的呢?这是要解决的第一个问题,这样才能做到APP与系统浏览器的内容差异化。

  • 通过域名
    将不同用途的页面归类到不同服务器或Web项目下,这是最简单也最笨的方法,如果同一个页面要在三端上都展示,那么就要复制3份了

  • 通过元数据

  • 通过UA标识
    这是web页面统计访问终端的品牌和分辨率的常用方法
    我会在WebView的默认UA后面,加上自定义的标识,包括APP的标识 (AndroidApp、iPhoneApp)、应用包名APP的版本号
    判断是否微信浏览器就可以使用这个方法,同时最好检查是否加载了微信自定义的weixin.js文件

配置WebView基础参数

final WebSettings settings = getSettings();//  允许JS弹出提示框settings.setJavaScriptCanOpenWindowsAutomatically(true);//  允许web执行JSsettings.setJavaScriptEnabled(true);//  设置浏览器标识settings.setUserAgentString(buildAppUserAgent(getContext(), settings.getUserAgentString()));//  是否支持缩放,默认不支持(看起来更native)settings.setSupportZoom(false);
settings.setBuiltInZoomControls(false);//  打开H5的离线缓存settings.setAppCacheEnabled(true);final String cachedir = getContext().getDir("cache", Context.MODE_PRIVATE).getPath();
settings.setAppCachePath(cachedir);//  打开H5的Dom Storage(localStorage,sessionStorage)settings.setDomStorageEnabled(true);//  如果要使用离线缓存和DomStorage必须要设置web databasefinal String dbdir = getContext().getDir("database", Context.MODE_PRIVATE).getPath();
settings.setDatabaseEnabled(true);
settings.setDatabasePath(dbdir);
登录后复制

WebViewClient对象

监听页面加载情况(开始加载、资源加载、完成加载、页面错误)

通常情况下,我们都会有一个loading界面覆盖在webview上面,当页面加载完成隐藏loading。
这里存在2个小问题:

  • webview只有当所有内容都加载完成后,才会回调onPageFinished。
    也就是说,当DOM元素加载完成,并且所有图片也加载完成才会触发,这对于追求体验的移动APP来说,显然无法接受。尤其是当网络不好或图片太大时尤为明显,用户看到的是明明页面已经基本出来了,却仍然在loading,无法操作。
    其实JS端可以监听到DOMContentLoaded事件,此时是关闭loading的最佳时机

  • 出现加载错误时,不仅会调用onReceivedError,仍然会调用onPageFinished
    有些人喜欢把loading界面和error界面写在同一个layout里,出现错误时显示error,完成加载时隐藏整个layout。
    这对于普通页面来说没有问题,但是对于webview就会出现error无法被显示的情况。
    所以最后将loading和error分开,在onPageFinished时,只需要隐藏loading部分。

拦截页面链接

重写shouldOverrideUrlLoading方法,当返回值为true时,需要自己处理url请求,webview将不会插手。
此方法只在涉及页面跳转时被触发。
这里存在2个问题:

  • 低版本的某些请求不会触发此方法,直接在本webview打开了新页面。
    如果想拦截,则需要在onPageStarted方法里判断url是否已经改变,更改了的话就表明打开了新的链接。

  • 页面重定向无法识别
    当页面存在重定向时,API并没有提供方法作区分,这时需要自己处理。

替换加载内容

重写shouldInterceptRequest方法,可以替换JS、CSS、img等内容。
创建WebResourceResponse对象,并传入文件输入流,即可用其他资源替换本来要加载的内容。
通过此方法,我们可以预先下载页面所需的JS和CSS文件,保存到本地;然后当打开页面时,直接使用本地已下载的文件。这样可以大幅提高页面加载速度。
注:此方法只能API Level 11以后使用,低版本可通过ContentProvider实现类似功能。

WebChromeClient对象

WebViewClient类主要设计链接和资源加载的功能实现
WebChromeClient类则会涉及更底层的内容,如控制台调试、JS弹出框、显示自定义view等。

替换Alert对话框

web页面一般会通过alert方法,显示一些提示信息,但是对话框的样式却因不同的品牌差异很大,为了使我们的APP保持统一风格,有必要替换成我们自己设计的对话框。
重写onJsAlert方法,将message显示到Dialog。
该方法是模态的,必须返回内容才能关闭对话框,调用JsResult.cancel或者JsResult.confirm。如果只调用了Dialog.dismiss而没有调用JsResult的方法,会出现,虽然对话框消失,但是线程一直处于阻塞状态,造成假死现象,无法进行任何操作。

全屏播放视频

webview默认不能全屏播放,需要client端提供全屏的window。
代码如下:

@Override
public void onShowCustomView (View view, WebChromeClient.CustomViewCallback callback) {
    mCustomViewCallback = callback;android.view.Window window = WebActivity.this.getWindow();window.setFlags(
            android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN,
            android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN);setRequestedOrientation(android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);mTitleBar.setVisibility(View.INVISIBLE);mWebView.setVisibility(View.INVISIBLE);mExitFullscreenBtn.setVisibility(View.VISIBLE);mVideoViewContainer.setVisibility(View.VISIBLE);mVideoViewContainer.addView(view);}

@Override
public void onHideCustomView () {
    mCustomViewCallback.onCustomViewHidden();android.view.Window window = WebActivity.this.getWindow();window.setFlags(0,
            android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN);setRequestedOrientation(android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);mTitleBar.setVisibility(View.VISIBLE);mWebView.setVisibility(View.VISIBLE);mExitFullscreenBtn.setVisibility(View.INVISIBLE);mVideoViewContainer.setVisibility(View.INVISIBLE);mVideoViewContainer.removeAllViews();}
登录后复制

Cookie

如果web端需要用户登录的操作,那么就涉及到native和web端同步登录状态,这就需要用到cookie。

//  打开Cookie支持CookieSyncManager.createInstance(this);
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setAcceptCookie(true);
登录后复制
//  设置cookie
sBuff.append(key).append("=").append(value);sBuff.append("; path=/");sBuff.append("; domain=").append(domain);cookieManager.setCookie(url, sBuff.toString());......
CookieSyncManager.getInstance().sync();
登录后复制
//  删除cookie//  清除过期的cookiecookieManager.removeExpiredCookie();//  清除所有cookiecookieManager.removeAllCookie();
登录后复制

因为并不存在单独删除cookie的某个字段的方法,所有要清除某个字段,要先将其设为已过期,再调用removeExpiredCookie

如何同步登录状态

简单的情况,只需要有userid即可认为已经登录,分如下两种情况:
- 先从native登录
native端调用登录接口,拿到useid后,当需要打开web时,在loadUrl之前,将userid保存到cookie中,服务端就会从cookie中读出userid。
- 先从web端登录
web登录后,webview会自动保存cookie。web端需要与native端定义接口,将username和userid通知给native端,native保存起来。

Web端与Native端互相通讯

WebView调用web端JS方法

mWebView.loadUrl("javascript:JSMethod()");
登录后复制

API 19以后,提供了更加便捷的方法,可以直接获取JS的返回值。(iOS本身已经提供类似API)

WebView.evaluateJavascript (String script, ValueCallback<String> resultCallback)
登录后复制

web端调用native代码

早期API提供的方法:

WebView.addJavascriptInterface(Object object, String name)
WebView会将object注入到web端的window对象中,name是object对象定义的方法,web端通过object.name即可调用native端的功能。
登录后复制

but,这个方法存在安全漏洞 漏洞详细说明
如果你的targetSdkVersion>=17,那么必须将java方法加上注解@JavascriptInterface,否则web端是无法调用的。

自定义scheme

通过自定义scheme的方式,在shouldOverrideUrlLoading拦截,并定向到相应的native逻辑。
iOS端需通过此方法实现。

利用WebChromeClient.onJsPrompt

因为JS端很少使用prompt(一般使用alert)方法,所以我们可以利用这个方法,通过自定义协议格式,来实现web与native端的通信。
因为此方法需要返回JsResult对象,所以利用此机制,可以实现方法的同步调用(web端可以获取到接口方法的返回值,有利于代码和逻辑的简化)
大名鼎鼎PhoneGap(现在叫Cordova)就是利用此方法实现的web与native通讯。

我会专门写一篇,我是如何实现web与native通信的。

其他技巧

屏蔽长按事件

重写performLongClick
或者setOnLongClickListener实现空的listener

隐藏选择框

可以使用全局的一个CSS
*{-webkit-tap-highlight-color: rgba(0, 0, 0, 0);}

缩放按钮引起的崩溃

在某些机型上,当显示webview的缩放按钮时,退出Activity,就会报如下错误:

android.view.WindowLeaked: Activity com.secoo.activity.web.WebActivity has leaked window android.widget.ZoomButtonsController$Container{438e8248 V.E..... ........ 0,0-1536,194} that was originally added here
    at android.view.ViewRootImpl.(ViewRootImpl.java:382)
    at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:261)
    at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:76)
    at android.widget.ZoomButtonsController.setVisible(ZoomButtonsController.java:371)
    ......
登录后复制

这是因为按钮的隐藏是延迟触发,在activity退出之后,造成了window的泄露。

解决方法:

//  API 11之后,不显示缩放按钮
WebView.getSettings().setDisplayZoomControls(false);//  API 11之前,在finish时,从view层级中删除webview
ViewGroup viewgroup = (ViewGroup)(mWebView.getParent());viewgroup.removeView(mWebView);
登录后复制

技术交流请留言…
To Be Continue…

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

<🎜>:泡泡胶模拟器无穷大 - 如何获取和使用皇家钥匙
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系统,解释
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆树的耳语 - 如何解锁抓钩
3 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Java教程
1670
14
CakePHP 教程
1428
52
Laravel 教程
1329
25
PHP教程
1273
29
C# 教程
1256
24
vivox100s和x100区别:性能对比及功能解析 vivox100s和x100区别:性能对比及功能解析 Mar 23, 2024 pm 10:27 PM

vivox100s和x100手机都是vivo手机产品线中的代表机型,它们分别代表了vivo在不同时间段内的高端技术水平,因此这两款手机在设计、性能和功能上均有一定区别。本文将从性能对比和功能解析两个方面对这两款手机进行详细比较,帮助消费者更好地选择适合自己的手机。首先,我们来看vivox100s和x100在性能方面的对比。vivox100s搭载了最新的

全角英文字母转换为半角形式的实用技巧 全角英文字母转换为半角形式的实用技巧 Mar 26, 2024 am 09:54 AM

全角英文字母转换为半角形式的实用技巧在现代生活中,我们经常会接触到英文字母,在使用电脑、手机等设备时也经常需要输入英文字母。然而,有时候我们会遇到全角英文字母的情况,而我们需要使用的是半角形式。那么,如何将全角英文字母转换为半角形式呢?下面就为大家介绍一些实用的技巧。首先,全角英文字母和数字是指在输入法中占据一个全角位置的字符,而半角英文字母和数字则是占据一

自媒体到底是什么?它的主要特点和功能有哪些? 自媒体到底是什么?它的主要特点和功能有哪些? Mar 21, 2024 pm 08:21 PM

随着互联网的快速发展,自媒体这个概念已经深入人心。那么,自媒体到底是什么?它有哪些主要特点和功能呢?接下来,我们将一一探讨这些问题。一、自媒体到底是什么?自媒体,顾名思义,就是自己就是媒体。它是指通过互联网平台,个人或者团队可以自主创建、编辑、发布和传播内容的信息载体。不同于传统媒体,如报纸、电视、电台等,自媒体具有更强的互动性和个性化,让每个人都能成为信息的生产者和传播者。二、自媒体的主要特点和功能有哪些?1.低门槛:自媒体的崛起降低了进入媒体行业的门槛,不再需要繁琐的设备和专业的团队,一部手

Win11小技巧分享:一招跳过微软账户登录 Win11小技巧分享:一招跳过微软账户登录 Mar 27, 2024 pm 02:57 PM

Win11小技巧分享:一招跳过微软账户登录Windows11是微软最新推出的操作系统,具有全新的设计风格和许多实用的功能。然而,对于一些用户来说,在每次启动系统时都要登录微软账户可能会感到有些烦扰。如果你是其中一员,不妨尝试一下以下的技巧,让你能够跳过微软账户登录,直接进入桌面界面。首先,我们需要在系统中创建一个本地账户,来代替微软账户登录。这样做的好处是

小红书账号管理软件有哪些功能?怎么经营小红书账号? 小红书账号管理软件有哪些功能?怎么经营小红书账号? Mar 21, 2024 pm 04:16 PM

随着小红书在年轻人中的流行,越来越多的人开始利用这一平台分享各方面的经验和生活见解。如何有效管理多个小红书账号成为一个关键问题。在本文中,我们将讨论一些小红书账号管理软件的功能,并探讨如何更好地经营小红书账号。随着社交媒体的发展,许多人发现自己需要管理多个社交账号。对于小红书用户来说,这也是一个挑战。一些小红书账号管理软件可以帮助用户更轻松地管理多个账号,包括自动发布内容、定时发布、数据分析等功能。通过这些工具,用户可以更高效地管理他们的账号,提高账号的曝光率和关注度。另一、小红书账号管理软件有

老手必备:C语言中*和&的技巧与注意事项 老手必备:C语言中*和&的技巧与注意事项 Apr 04, 2024 am 08:21 AM

C语言中,表示指针,存储其他变量的地址;&表示地址运算符,返回变量的内存地址。指针的使用技巧包括定义指针、解引用指针,需确保指针指向有效地址;地址运算符&的使用技巧包括获取变量地址,获取数组元素地址时返回数组第一元素地址。实战案例说明了使用指针和地址运算符反转字符串。

新手制作表格有哪些技巧 新手制作表格有哪些技巧 Mar 21, 2024 am 09:11 AM

我们经常在excel中制作和编辑表格,但是作为一个刚刚接触软件的新手来讲,如何使用excel制作表格,并没有我们使用起来那么轻松。下边,我们针对新手,也就是初学者需要掌握的表格制作的一些步骤进行一些演练,希望对需要的人有些帮助。新手表格示例样板如下图:我们看看如何来完成!1,新建excel文档,有两种方法。可以在【桌面】空白位置,点击鼠标右键-【新建】-【xls】文件。也可以【开始】-【所有程序】-【MicrosoftOffice】-【MicrosoftExcel20**】2,双击我们新建的ex

VSCode入门指南:初学者必读,快速掌握使用技巧! VSCode入门指南:初学者必读,快速掌握使用技巧! Mar 26, 2024 am 08:21 AM

VSCode(VisualStudioCode)是一款由微软开发的开源代码编辑器,具有强大的功能和丰富的插件支持,成为开发者们的首选工具之一。本文将为初学者们提供一个入门指南,帮助他们快速掌握VSCode的使用技巧。在本文中,将介绍如何安装VSCode、基本的编辑操作、快捷键、插件安装等内容,并为读者提供具体的代码示例。1.安装VSCode首先,我们需

See all articles