美文网首页Android TechWebViewAndroid开源框架
Android-X5WebView封装(含Cookie管理、优化

Android-X5WebView封装(含Cookie管理、优化

作者: 骑小猪看流星 | 来源:发表于2018-03-14 15:05 被阅读3402次

本文已独家授权 郭霖 ( guolin_blog ) 公众号发布!

撸完了上一篇Android-X5WebView简介 之后,有些大兄弟可能觉得不过瘾呐,说你那样的都是很基础的啊(的确很基础),项目里面用起来不爽啊(的确很不爽),不能让我直接CV啊(的确不能直接复制粘贴)等等,那这篇文章的目标就是怎么样快速封装X5WebView,如何有效的同步以及管理Cookie,如何使用IntentService优化预加载,如何监听进度条等一些在项目中的常用功能。

功能需求:

需求一:客户端账号密码登录成功以后,调用H5(也就是使用X5webView,以下简称X5)。H5界面也需要去记录你的状态。比如你客户端本地登录成功以后,H5界面也需要显示登录成功的状态。那么,客户端和H5如何去同步状态?

需求二:因为X5加载的时候,会有一段时间会显示空白或者卡顿,如何去监听并利用这个进度并优化?

需求三:如何简单封装X5WebView基本功能,方便日后快速使用?

需求分析:

需求一:

(针对需求一,真的是参考了很多哥们的技术博客,然后由于笔者上周也就是3月9号接到的开发需求,其中遇到了很多坑,所以我希望这篇博客可以把这个需求写的详细,尽可能的造福以后遇到同样需求的朋友让他们节约时间少走弯路)

对于Cookie,我们并不陌生,如果不是很了解的建议首先参考Cookie、Session、Token那点事儿  先大致掌握一下。这里多提一嘴,Cookie 简单理解,它主要是用来进程保活的,其具有时效性(持久化和非持久化),它是通过服务器的请求,在响应头里面拿到,然后在第二次http请求上以请求头的方式将参数带过去,优点是减少后台查库压力等等,更加具体的细节和说明可以参考上面的链接文章,那么,在Android中,也就是WebView中,我们如何去管理Cookie?

首先:CookieSyncManager与CookieManager

Android中关于Cookie的说明:

早期的cookie是由CookieSyncManager进行管理的,之后CookieSyncManager被抛弃了,换成了CookieManager来进行管理。两个版本的分割线就是Android SDK -- 21。

Android中Cookie的存储位置:

目前Android系统WebView是将cookie存储data/data/package_name/app_webview这个目录下的一个叫Cookies的数据中。

CookieSyncManager在内存和存储器之间同步浏览器的cookie。另外,CookieSyncManager的同步策略是在一个独立的线程里定时进行同步。

注意:每次同步的时间间隔是5分钟。

CookieSyncManager类下的常用API介绍

cookie同步策略:

CookieSyncManager.createInstance(context); 

CookieSyncManager.getInstance().startSync();

cookie停止同步:

CookieSyncManager.getInstance().stopSync()

cookie立即同步:调用了该方法会立即进行cookie的同步,代码如下:

CookieSyncManager.getInstance().sync()

删除cookie操作:

CookieSyncManager.createInstance(this);

CookieManager.getInstance().removeAllCookie();

CookieManager.getInstance().removeSessionCookie();

CookieSyncManager.getInstance().sync();

CookieSyncManager.getInstance().startSync();

CookieManager管理cookie:从sdk21之后,webview已经内置了cookie的同步操作了。虽然不再需要关注cookie的同步,但是依然需要掌握删除cookie的操作。

删除cookie操作:底层实现是异步清除数据库的记录

CookieManager.getInstance().removeAllCookies(null);

CookieManager.getInstance().flush();

立即同步:注意到这个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对象传进去,即可完成进度监听。

监听进度

需求三:封装X5Webview基本功能

常用设置:

比如设置对JS的支持等等一些比较常用的,我们可以直接这样设置

常用设置

滚动条(内侧、外侧的设置),隐藏或显示的基本使用:

滚动条属性设置

处理预加载:

有的小伙伴说,X5预加载不是很友好。在加载X5内核的时候,X5内核需要进行一些初始化,这些初始化如果不明确指出运行的线程,它就会在你启动页面的时候,默认在主线程中执行,因此就会出现卡顿(这个现象时有时无,但是我们在代码层面尽可能的去规避使用风险),所以,我们可以写个 IntentService 去帮我们管理预加载问题:

IntentService

多提一嘴:IntentService是Service的子类,比普通的Service增加了额外的功能。

IntentService会创建独立的worker线程来处理所有的Intent请求;

会创建独立的worker线程来处理onHandleIntent()方法实现的代码,无需处理多线程的问题;

所有请求处理完成后,IntentService会自动停止,开发者无需手动调用stopSelf()方法停止Service;

写完之后我们在去自定义Application里面注册服务:(别忘了去清单文件配置Services)

Application使用service

返回键的处理:

这个就根据大家开发需求具体使用了,有的要求返回键按下两次才允许退出等等

生命周期的处理、释放资源的处理:这个就不说了,大家查阅资料集成功能即可

拦截广告的处理:

有些哥们说,使用这个经常会出现广告,解决这个办法有两个办法

1:使用Https

2:设计拦截url规则,对允许的url进行放行加载,不允许的url,WebView禁止加载

附录:项目地址

如果觉得这篇文章对你有帮助,希望点下一个小小的star,谢谢。

Ps:著作权归作者所有,转载请注明作者, 商业转载请联系作者获得授权,非商业转载请注明出处(开头或结尾请添加转载出处,添加原文url地址),文章请勿滥用、开源项目仅供学习交流、也希望大家尊重笔者的劳动成果,谢谢。

相关文章

  • Android-X5WebView封装(含Cookie管理、优化

    本文已独家授权 郭霖 ( guolin_blog) 公众号发布! 撸完了上一篇Android-X5WebView简...

  • javascript常见函数2

    设置cookie 获取cookie 移除指定名称cookie json转字符串 ajax封装 jsonp封装 正则...

  • 前端Cookie基本使用方法

    Cookie Cookie特点 Cookie内存大小受限 Cookie具有生命周期 Cookie满足同源策略 封装...

  • cookie

    //设置cookie //获取cookie //封装cookie调用 以对象的形式获取 //key // 设置有效...

  • 性能优化

    内容优化 服务器优化 Cookie优化 CSS优化 javascript优化 图像优化

  • flutter网络请求相关的好文

    Flutter 网络请求封装之Dio(Cookie管理、添加拦截器、下载文件、异常处理、取消请求等) https:...

  • Cookie

    设置cookie 获取cookie 封装cookie调用 以对象的形式获取 key 设置有效期:

  • 前端性能优化

    AJax 优化 缓存 Ajax 请求尽量使用GET, 仅取决于cookie数量 Cookie 优化 减少Cooki...

  • 七天免登录JavaScript实现

    html代码 JS代码封装cookie

  • 会话

    Cookie API 为了封装cookie信息在Cookie API中提供了一个javax.servlet.htt...

网友评论

  • cjcj125125:api 21 以下需要改为 com.tencent.smtt.sdk.CookieSyncManager.createInstance(App.getInstance()).getInstance().sync(); 原本为com.tencent.smtt.sdk.CookieSyncManager.getInstance().sync(); 不然会出问题
  • zzjian:请教一下,x5如何清除播放视频缓存的数据?太大了而且也不知道藏哪里了
  • willwaywang6:请教一下: 在无网络时, 安装 app 并启动, 直接闪退, 查看日志, 指向了 x5 的 JNI 调用(这个问题可以在官方的 demo 上复现)? 如果在 Application 里加网络判断, 决定是否初始化 x5, 那么进入应用后, 点击使用 x5 的详情页面, 还是闪退. 请问这个在项目中怎么解决的? 我是刚使用 x5 的.
    willwaywang6:@骑小猪看流星 我的手机是华为荣耀6 Android6.0 Android studio targetSdkVersion 22 minSdkVersion 16 compileSdkVersion 27, 我自己再研究研究, 谢谢大神.
    骑小猪看流星:理论上 X5内核如果初始化加载失败 会切换到系统内核。刚才我关闭了流量,打开应用(也是X5加载H5),并没有出现你说的闪退(机型:中兴 C880U、手机系统版本Android 5.1、Android studio targetSdkVersion 26 minSdkVersion 16 、compileSdkVersion 26)
  • 魏魏魏魏:老哥,你好!郭神公众号过来的,请教一个问题:你有遇到过pre标签内的代码在X5无法自动换行的情况吗?浏览器正常,就WebView里面不行?
    <pre class="prettyprint prettyprinted" style=""><span class="kwd">public</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">Bottle</span><span class="pln"> </span><span class="kwd">implements</span><span class="pln"> </span><span class="typ">Packing</span><span class="pln"> </span><span class="pun">{</span><span class="pln">

    </span><span class="lit">@Override</span><span class="pln">
    </span><span class="kwd">public</span><span class="pln"> </span><span class="typ">String</span><span class="pln"> pack</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">return</span><span class="pln"> </span><span class="str">"Bottle"</span><span class="pun">;</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
    </span><span class="pun">}</span></pre>
    骑小猪看流星:有个比较简单的测试方法可以解决你的问题,微信使用的是X5内核,可以将Html链接放在微信里面进行检验
  • Passon_Fang:第一次启动应用的时候,无法加载内核 有遇到过吗?
    骑小猪看流星:文章新增内容已经给了解决办法 望知悉
    Passon_Fang:建议不要使用 IntentService, 这个会导致初次启动应用无法加载内核
  • b90cc3be278a:特地登录点赞,老铁,稳!
    骑小猪看流星::grin: 谢谢老哥
  • thaixp:牛
  • 259c1c37b7cc:x5内核有多大。不依赖微信的内核的情况下
    ZZombiee:初始化X5,内存升50M
  • monkey_who:郭神公众号看到了
  • 清明捉鬼:我之前做项目时遇到过访问webView,所产生两次的cookie不同,不知道作者遇到过么?
    骑小猪看流星:嗯 遇到过的 github上项目里面的方法可以解决cookie同步的问题额 ( 而且已经用到自己的项目里面去了)
  • Dinos:求带一波烤鱼
    骑小猪看流星::yum: 老铁没毛病:yum:
  • 2248a4e2216e:我湖北鸽子王能神关注你很久了
    骑小猪看流星::yum: 有机会一起吃烤鱼

本文标题:Android-X5WebView封装(含Cookie管理、优化

本文链接:https://www.haomeiwen.com/subject/awhofftx.html