Android-X5WebView封装(Cookie管理、进度监听、适配8.1
系统等策略)
本⽂已独家授权 郭霖 ( guo lin_blo g ) 发布!党员个人自我评价
撸完了上⼀篇Android-X5WebView简介 之后,有些⼤兄弟可能觉得不过瘾呐,说你那样的都是很基础的啊(的确很基础),项⽬⾥⾯⽤起来不爽啊(的确很不爽),不能让我直接CV啊(的确不能直接复制粘贴)等等,那这篇⽂章的⽬标就是怎么样快速封装X5WebView,如何有效的同步以及管理Cookie,如何使⽤IntentService优化预加载,如何监听进度条以及8.1系统的踩坑适配,等⼀些在项⽬中的常⽤功能。
⽂章⽤到的源码:项⽬地址
最近更新内容:
X5Webview适配Android 8.1系统
Https与Http混合加载
黄晓明和秦岚
功能需求
需求⼀:客户端账号密码登录成功以后,调⽤H5(也就是使⽤X5webView,以下简称X5)。H5界⾯也需要去记录你的状态。⽐如你客户端本地登录成功以后,H5界⾯也需要显⽰登录成功的状态。那么,客户端和H5如何去同步状态?
需求⼆:因为X5加载的时候,会有⼀段时间会显⽰空⽩或者卡顿,如何去监听并利⽤这个进度并优化?
需求三:如何简单封装X5WebView基本功能,⽅便⽇后快速使⽤?
需求分析:
需求⼀:
(针对需求⼀,真的是参考了很多哥们的技术博客,然后由于笔者上周也就是3⽉9号接到的开发需求,其中遇到了很多坑,所以我希望这篇博客可以把这个需求写的详细,尽可能的造福以后遇到同样需求的朋友让他们节约时间少⾛弯路)
对于Cookie,我们并不陌⽣,如果不是很了解的建议⾸先参考Cookie、Session、Token那点事⼉  先⼤致掌握⼀下。这⾥多提⼀嘴,Cookie 简单理解,它主要是⽤来进程保活的,其具有时效性(持久化和⾮持久化),它是通过服务器的请求,在响应头⾥⾯拿到,然后在第⼆次http请求上以请求头的⽅
式将参数带过去,优点是减少后台查库压⼒等等,更加具体的细节和说明可以参考上⾯的链接⽂章,那么,在Android中,也就是WebView中,我们如何去管理Cookie?
CookieManager
CookieSyncManager与CookieManager
⾸先:CookieSyncManage
Android中关于Cookie的说明:
早期的cookie是由CookieSyncManager进⾏管理的,之后CookieSyncManager被抛弃了,换成了CookieManager来进⾏管理。两个版本的分割线就是Android SDK -- 21。
Android中Cookie的存储位置:
⽬前Android系统WebView是将cookie存储data/data/package_name/app_webview这个⽬录下的⼀个叫Cookies的数据中。
CookieSyncManager在内存和存储器之间同步浏览器的cookie。另外,CookieSyncManager的同步策略是在⼀个独⽴的线程⾥定时进⾏同CookieSyncManage
步。
注意:每次同步的时间间隔是5分钟。
CookieSyncManager类下的常⽤API介绍
CookieSyncManager
cookie同步策略:
cookie停⽌同步:
cookie⽴即同步:调⽤了该⽅法会⽴即进⾏cookie的同步,代码如下:
删除cookie操作:
撩到对象流黄水的污句子
CookieManager管理cookie:从sdk21之后,webview已经内置了cookie的同步操作了。虽然不再需要关注cookie的同步,但是依然需要掌CookieManager
握删除cookie的操作。
删除cookie操作:底层实现是异步清除数据库的记录
⽴即同步:注意到这个flush()⽅法就是⽴即同步cookie的操作,本质上与CookieSyncManager中的sync()⽅法是⼀样的。于是乎,关于同步cookie我们可以有如下简单的写法:
cookie同步
然后,笔者就遇到了第⼀个坑,按照如下写法以后,cookie居然神奇的不同步(下⾯是伪代码,下⾯是伪代码)
cookie不同步
之前笔者通过字符串拼接,也就是append字符串 ,拼接字符串以后,我想直接通过cookieManager.setCookie(url, cookie); 在
x5WebView.loadUrl(url);调⽤之前去设置cookie,
然后,cookie就是同步不了。没得办法,打印⽇志之后发现,⼿动设置的cookie值,神奇的只有⼀个分号 !
坤音四子⾕歌百度后,有哥们说是因为cookie Value的值在读取时,只会读取到第⼀个分号时,当发现第⼀个分号即认为读取结束。所以分号后⾯的cookie的值将不会读取,实际测试确实是这样。那么,我们该如何解决拼接cookie读取失败的问题?
解决办法如下图,我们可以⼀个个⼿动设置cookie,即可拼接完整的Cookie。(这种办法虽然笨拙,但的确可以有效解决分号切割问题)
setCookie解决办法艾德 维斯特维克
当然,我在公司项⽬⾥⽤的是Okhttp,(为什么这⾥⽤Okhttp,因为!这样就可以⽤Okhttp、Retrofit、OkGo等⽹络框架,直接集成 我在项⽬中给⼤家提供的、⾃定义CookieJar使⽤了)。通过⾃定义,实现CookieJar去完成同步客户端和H5的cookie状态。这⾥先上下最终效果图:(笔者的代码可能不是唯⼀实现功能需求的,但凑合还能⽤。实现⽅式有很多种,写的不好也请⼤家见谅)
Okhttp简单设置
关于AddCookiesInterceptor以及SaveCookiesInterceptor这两个,主要就是存Cookie和使⽤Cookie,具体说明可以参考 两个的说明 ,然后我们点进⾃定义cookieJar中的 SaCookieManger
SaCookieManger
这个类定义了⼀个context构造参数,在保存cookie的saveFromResponse⽅法中,调⽤了
SaasCookieManager.loadCookie(cookies,url.host());⽅法,我们点进SaasCookieManager
SaasCookieManager
通过遍历添加到集合⾥⾯,然后⼀个个的setCookie( url ,cookie )、接着判断SDK版本号进⾏同步刷新即可,具体可以参考项⽬源代码。
当然⼤家也可以在这⾥⾯根据开发需求去增加⾃⼰的实际功能。
通过上⾯的步骤,我们就可以简单的实现 客户端与H5端同步cookie。
笔者的项⽬⾥⾯,是客户端登录成功以后,进⼊H5页⾯,H5页⾯上直接显⽰已登录状态。
拓展:有部分⼿机使⽤后可能还是⽆法同步,那么我们可以尝试,设置跨域读取cookie,开启webview对第三⽅cookie的⽀持。
跨域查询
关昕照片当页⾯加载完毕的时候,我们可以通过下⾯的截图代码,去获取H5上⾯的cookie,我们也可以打印⽇志、进⾏同步
页⾯加载完毕
需求⼆:
监听进度,是这样,WebView⾥⾯的WebChromeClient这个类,⾥⾯有个onProgressChanged⽅法,重写这个⽅法就可以获取加载进度。获取到X5Webview的进度之后,还需要通过WebView的setWebChromeClient⽅法,将我们⾃定义的WebChromeClient对象传进去,即可完成进度监听。