[Android] Webview利用CookieSyncManager获取或设置Cookies的策略

来源:互联网 发布:g1x mark ii 知乎 编辑:程序博客网 时间:2024/04/28 19:21

应用场景

或许, 你也有碰到过这样的应用场景:

APP应用的某些功能, 需要调用内嵌的WebView去加载某个URL使用.  但用户在手机APP已经成功登录过了. 这时, 如果在内置浏览器去打开网页还需要用户再输入登录一次, 似乎显得不够人性化.  又或者, 用户在内置浏览器(WebView) 访问过一些页面, 想把这些有用的 Cookies 信息保存在本地.  因此, 我们会想, 要是能管理APP上浏览器(WebView) 在该站点URL的 Cookies, 使后台识别为已登录, 蛮不错的~   这里我们使用 CookieSyncManager 来实现.


小谈CookieSyncManager 

翻看这类 - CookieSyncManager, 机智的你一定发现官方已经给它打上一个可爱的 @Deprecated .  为啥子呢? 

 * * @deprecated The WebView now automatically syncs cookies as necessary. *             You no longer need to create or use the CookieSyncManager. *             To manually force a sync you can use the CookieManager *             method {@link CookieManager#flush} which is a synchronous *             replacement for {@link #sync}. */

这是该类的介绍. 原来现在的 WebView 已经具备自动同步cookies 的功能, 所以不再需要人为去创建或使用 CookieSyncManager.  简单地说, 就是新的WebView已经足够强大, 可以自己去管理访问站点的Cookies. 当然, 针对某些特殊情况, 依旧提供了人工强制的同步Cookies 的方法:

if (Build.VERSION.SDK_INT < 21) {CookieSyncManager.getInstance().sync();} else {CookieManager.getInstance().flush();}

比如上面说的应用场景,  假设目标站点URL为 http://testcookie.mobile.xxx.com/, 浏览器(WebView) 先前没有访问过这个站点, 就不存在这个站点的Cookies, 但是你又想第一次访问就携带一些用户信息, 比如将用户的userId, groupId,之类的信息放进去, 方便服务器进行认证和权限管理. 甚至免去二次登录的麻烦. 这时, 就需要我们人工设置WebView 的Cookies. 所以说, CookieSyncManager 虽然已经被Deprecated 掉, 还是有一定用处的.


CookieSyncManager 类的代码非常少, 我们只关心几个关键的方法就足够用了.


使用CookieSyncManager 前, 要先去创建:

CookieSyncManager.createInstance(context);


开始同步:

CookieSyncManager.getInstance().startSync();


停止同步, 官方建议在Activity.onResume() 中调用:

CookieSyncManager.getInstance().stopSync();

因为自动同步的时间间隔是5分钟, 这个时间间隔也许显得过长, 并不能保证及时的保存有效有用的Cookies. 所以我们就可以人为去同步保存它:

if (Build.VERSION.SDK_INT < 21) {CookieSyncManager.getInstance().sync();} else {CookieManager.getInstance().flush();}
什么时候去调用呢?  可以在浏览器的关键周期方法调用, 比如WebViewClient 的 onPageFinished(). 同时在Activity 的 onPause() 周期方法等等. 这样, 就能有效的保证Cookies能及时被同步保存.


移除Session Cookie:

removeSessionCookie();
比如用户已经登录, 调用该方法后, 再次访问该站点, 就会变成未登录的状态.

CookieSyncManager 对Cookies 的管理策略究竟是怎样的? 

大家知道, Cookies 都有有效期, 过了有效期自然无效. CookieSyncManager 会开一个单独的定时器线程去保存(间隔为5mins) Cookies. 线程会在设备的RAM 和 本地永久化存储

之间去维护这些Cookies. 举个例子, 当人为的调用 CookieSyncManager.getInstance().sync() 同步了Cookies. 然后退出账号的登录, 重启APP应用, 甚至重启手机设备, 再次打开应用进入到对应的WebView, 会奇怪的发现, 居然还是已登录状态... 顿时风中凌乱... 因此, 比如应用里退出账号后, 应当及时将浏览器的session对话移除掉.


OK. 来到这里, 我们已经对CookieSyncManager 有一定了解囖. 下面的代码, 看起来就So easy了~


实现过程

首先, 假设目标站点URL为 http://testcookie.mobile.xxx.com/ . 我们来实现上面说的应用场景: 用户在应用已经登录了, 希望打开目标站点时就已经是登录状态, 而不再需要在网页二次登录. 应用内登录后的用户有一串识别用的Cookies (下面模拟数据, 但是实际中我使用真实数据和站点做测试的 == ) :

UID=EBFDA984906B62C444931EA0SID=EBFDA984906BEE91F90362C444931EA0PSTM=14572770TTDSS=Hl3NVU0N3ltZm9OWHhubHVQZW1BRThLdGhLaFc5TnVtQWd1S2g1REcwNVhTS3RXQVFBQ


要将这一串 Cookies 要添加到 WebView ,  然后 LoadUrl(), 就算成功. 

CookieSyncManager.createInstance(this);CookieManager cookieManager = CookieManager.getInstance();cookieManager.setAcceptCookie(true);String url = "http://testcookie.mobile.xxx.com/";cookieManager.setCookie(url, "UID=EBFDA984906B62C444931EA0");cookieManager.setCookie(url, "SID=EBFDA984906BEE91F90362C444931EA0");cookieManager.setCookie(url, "PSTM=14572770");cookieManager.setCookie(url, "TTDSS=Hl3NVU0N3ltZm9OWHhubHVQZW1BRThLdGhLaFc5TnVtQWd1S2g1REcwNVhTS3RXQVFBQ");if (Build.VERSION.SDK_INT < 21) {CookieSyncManager.getInstance().sync();} else {CookieManager.getInstance().flush();}
这里有个小坑... 设置Cookie 的值, 每一对 key-value 需要分开设置, 不能这样写:

cookieManager.setCookie(url, "SID=EBFDA984906BEE91F90362C444931EA0;PSTM=14572770;TTDSS=Hl3NVU0N3ltZm9OWHhubHVQZW1BRThLdGhLaFc5TnVtQWd1S2g1REcwNVhTS3RXQVFBQ;");

这时, 再去访问站点:

mWebView.loadUrl("http://testcookie.mobile.xxx.com/");
就发现, 站点已经显示为登录状态. 也许你会说, 搞毛, 根本没成功好吧!!!   是这样的兄弟, 这个... 还需要后台的配合. 就是说, 你设置Cookies后去访问该站点, 网站开发的人应当对你的 Cookies 信息做处理, 比如根据不同的UID, token什么, 赋予不同的用户权限, 判断登录和未登录状态等等.

设置 Cookies 的操作已经成功. 需要移除时, 直接这样:

CookieSyncManager.createInstance(context);CookieManager cookieManager = CookieManager.getInstance();cookieManager.removeSessionCookie();if (Build.VERSION.SDK_INT < 21) {CookieSyncManager.getInstance().sync();} else {CookieManager.getInstance().flush();}

关于获取站点 Cookies 的方法, 既然有 setCookie, 应当也有 getCookie 吧. 去看看, 果然有耶:

cookieManager.getCookie(url);

以上就是文章的内容, 希望能给予你一点帮助. ^^


5 0
原创粉丝点击