目錄
引子
准备
区分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 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 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教學
1667
14
CakePHP 教程
1426
52
Laravel 教程
1328
25
PHP教程
1273
29
C# 教程
1255
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