转自:http://blog.youkuaiyun.com/b275518834/article/details/51004237
类似参考:http://blog.sina.com.cn/s/blog_623868100101jlxz.html
这是在网上抄的cookie设置方案,在android 5.0系统上测试时正常在,在部分4.X手机上测试有时会失效
(我使用的测试机为中兴 ZTE android版本4.3 )
- public void syncCookie(Context context,String url,String value) {
-
- try {
- CookieSyncManager.createInstance(context);
- CookieManager cookieManager = CookieManager.getInstance();
- cookieManager.setAcceptCookie(true);
- cookieManager.removeSessionCookie();
- cookieManager.setCookie(url,value);
- CookieSyncManager.getInstance().sync();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
最终解决方案是
http://code.walletapp.net/post/46414301269/passing-cookie-to-webview
但是解决问题的人回答是
In few following lines I will describe my solution, how to pass cookies from DefaultHttpClient to WebView component. I was following many tutorials, but cookies weren’t send to WebView properly (in my Android 2.2). After several experiments I found out that it is working, when we wait a little time between removeSessionCookie and setCookie methods. I don’t know why. But important is, that it is working right now for me.
在removeSessionCookie和setCookie方法之间需要加入等待时间,设置cookie成功,但是不知道为什么。
解决方案是等待了1000毫秒,实际应该不需要这么长的时间
我们去android 源码在线网站上看看
http://grepcode.com/project/repository.grepcode.com/java/ext/com.google.android/android/
在android 4.0上removeSeesionCookie的代码 开启了AsyncTask的异步任务处理cookie。也就是说removeSeesionCookie这段代码是在4.0的系统上异步的
所以cookieManager.removeSeesionCookie() 异步会导致删除setcookie的内容,所以有时成功有时失败
- public void More ...removeSessionCookie() {
- 610 signalCookieOperationsStart();
- 611 if (JniUtil.useChromiumHttpStack()) {
- 612 new AsyncTask<Void, Void, Void>() {
- 613 protected Void More ...doInBackground(Void... none) {
- 614 nativeRemoveSessionCookie();
- 615 signalCookieOperationsComplete();
- 616 return null;
- 617 }
- 618 }.execute();
- 619 return;
- 620 }
- 621
- 622 final Runnable clearCache = new Runnable() {
- 623 public void More ...run() {
- 624 synchronized(CookieManager.this) {
- 625 Collection<ArrayList<Cookie>> cookieList = mCookieMap.values();
- 626 Iterator<ArrayList<Cookie>> listIter = cookieList.iterator();
- 627 while (listIter.hasNext()) {
- 628 ArrayList<Cookie> list = listIter.next();
- 629 Iterator<Cookie> iter = list.iterator();
- 630 while (iter.hasNext()) {
- 631 Cookie cookie = iter.next();
- 632 if (cookie.expires == -1) {
- 633 iter.remove();
- 634 }
- 635 }
- 636 }
- 637 CookieSyncManager.getInstance().clearSessionCookies();
- 638 signalCookieOperationsComplete();
- 639 }
- 640 }
- 641 };
- 642 new Thread(clearCache).start();
- 643 }
另外4.X的CookieManager的sync()也是异步的 以下是代码段
开启一个mHandler(SyncHandler)等待100毫秒 调用 syncFlushCookieStor()->flushCookieStore()->nativeFlushCookieStore() (这句才是真正将cookiet同步的代码)
- public void More ...sync() {
- 97 if (DebugFlags.WEB_SYNC_MANAGER) {
- 98 Log.v(LOGTAG, "*** WebSyncManager sync ***");
- 99 }
- 100 if (mHandler == null) {
- 101 return;
- 102 }
- 103 mHandler.removeMessages(SYNC_MESSAGE);
- 104 Message msg = mHandler.obtainMessage(SYNC_MESSAGE);
- 105 mHandler.sendMessageDelayed(msg, SYNC_NOW_INTERVAL);
- 106 }
- private class More ...SyncHandler extends Handler {
- 47 @Override
- 48 public void More ...handleMessage(Message msg) {
- 49 if (msg.what == SYNC_MESSAGE) {
- 50 if (DebugFlags.WEB_SYNC_MANAGER) {
- 51 Log.v(LOGTAG, "*** WebSyncManager sync ***");
- 52 }
- 53 syncFromRamToFlash();
- 54
- 55
- 56 Message newmsg = obtainMessage(SYNC_MESSAGE);
- 57 sendMessageDelayed(newmsg, SYNC_LATER_INTERVAL);
- 58 }
- 59 }
- 60 }
- protected void More ...syncFromRamToFlash() {
- if (DebugFlags.COOKIE_SYNC_MANAGER) {
- Log.v(LOGTAG, "CookieSyncManager::syncFromRamToFlash STARTS");
- }
-
- CookieManager manager = CookieManager.getInstance();
-
- if (!manager.acceptCookie()) {
- return;
- }
-
- manager.flushCookieStore();
-
- if (DebugFlags.COOKIE_SYNC_MANAGER) {
- Log.v(LOGTAG, "CookieSyncManager::syncFromRamToFlash DONE");
- }
- }
在android5.0系统上Sync回调用flush()方法
- @Deprecated
- 115 protected void More ...syncFromRamToFlash() {
- 116 CookieManager.getInstance().flush();
- 117 }
另外android 5.0官方文档上面也说明了
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 methodCookieManager.flush()
which is a synchronous replacement for sync()
.
webview现在必须自动同步cookie,你不再需要创建或使用cookiesyncmanager,你可以使用CookieManager的CookieManager.flush()方法,flush()是sync()同步置换
结论在android4.X系统下面cookiesyncmanager的方法有些事异步的,removeSeesionCookie()和sync()要等待100毫秒。
而在android5.0以上的系统Cookie是同步的,sync=flush方法,调用CookieManager.flush()就是同步设置cookie。