android上WebView设置cookie,以及设置webview cookie在部分手机失效

来源:互联网 发布:网络被攻击了怎么办 编辑:程序博客网 时间:2024/06/11 21:19

转自:http://blog.csdn.net/b275518834/article/details/51004237

类似参考:http://blog.sina.com.cn/s/blog_623868100101jlxz.html


这是在网上抄的cookie设置方案,在android 5.0系统上测试时正常在,在部分4.X手机上测试有时会失效

(我使用的测试机为中兴  ZTE android版本4.3 )

[java] view plain copy
 print?
/**
*在android里面在调用webView.loadUrl(url)之前一句调用此方法就可以给WebView设置Cookie 
  注:这里一定要注意一点,在调用设置Cookie之后不能再设置
Java代码  收藏代码
  1. webView.getSettings().setBuiltInZoomControls(true);  
  2. webView.getSettings().setJavaScriptEnabled(true);  
   这类属性,否则设置Cookie无效。
*/
  1. public void syncCookie(Context context,String url,String value) {  
  2.   
  3.        try {  
  4.            CookieSyncManager.createInstance(context);  
  5.            CookieManager cookieManager = CookieManager.getInstance();  
  6.            cookieManager.setAcceptCookie(true);  
  7.            cookieManager.removeSessionCookie();  
  8.            cookieManager.setCookie(url,value);  
  9.            CookieSyncManager.getInstance().sync();  
  10.        } catch (Exception e) {  
  11.            e.printStackTrace();  
  12.        }  
  13.    }  


最终解决方案是

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的内容,所以有时成功有时失败

[java] view plain copy
 print?
  1. public void More ...removeSessionCookie() {  
  2. 610         signalCookieOperationsStart();//某个变量值+1  
  3. 611         if (JniUtil.useChromiumHttpStack()) {  
  4. 612             new AsyncTask<Void, Void, Void>() {  
  5. 613                 protected Void More ...doInBackground(Void... none) {  
  6. 614                     nativeRemoveSessionCookie();  //移除本地所有会话的cookie  
  7. 615                     signalCookieOperationsComplete();//某个变量值-1 并断言 相当于log  
  8. 616                     return null;  
  9. 617                 }  
  10. 618             }.execute();//启动异步任务  
  11. 619             return;  
  12. 620         }  
  13. 621   
  14. 622         final Runnable clearCache = new Runnable() {  
  15. 623             public void More ...run() {  
  16. 624                 synchronized(CookieManager.this) {   //移除所有内存中的cookie映射  
  17. 625                     Collection<ArrayList<Cookie>> cookieList = mCookieMap.values();  
  18. 626                     Iterator<ArrayList<Cookie>> listIter = cookieList.iterator();  
  19. 627                     while (listIter.hasNext()) {  
  20. 628                         ArrayList<Cookie> list = listIter.next();  
  21. 629                         Iterator<Cookie> iter = list.iterator();  
  22. 630                         while (iter.hasNext()) {  
  23. 631                             Cookie cookie = iter.next();  
  24. 632                             if (cookie.expires == -1) {  
  25. 633                                 iter.remove();  
  26. 634                             }  
  27. 635                         }  
  28. 636                     }  
  29. 637                     CookieSyncManager.getInstance().clearSessionCookies();//清空所有会话的cookie  
  30. 638                     signalCookieOperationsComplete();  
  31. 639                 }  
  32. 640             }  
  33. 641         };  
  34. 642         new Thread(clearCache).start();//启动线程  
  35. 643     }  



另外4.X的CookieManager的sync()也是异步的  以下是代码段

开启一个mHandler(SyncHandler)等待100毫秒 调用 syncFlushCookieStor()->flushCookieStore()->nativeFlushCookieStore() (这句才是真正将cookiet同步的代码)


[java] view plain copy
 print?
  1. public void More ...sync() {  
  2. 97         if (DebugFlags.WEB_SYNC_MANAGER) {  
  3. 98             Log.v(LOGTAG, "*** WebSyncManager sync ***");  
  4. 99         }  
  5. 100        if (mHandler == null) {  
  6. 101            return;  
  7. 102        }  
  8. 103        mHandler.removeMessages(SYNC_MESSAGE);  
  9. 104        Message msg = mHandler.obtainMessage(SYNC_MESSAGE);  
  10. 105        mHandler.sendMessageDelayed(msg, SYNC_NOW_INTERVAL); //等待<span style="font-family: 'Lucida Grande', Tahoma, Verdana, Arial, Helvetica, sans-serif;">SYNC_NOW_INTERVAL=</span><span style="font-family: 'Lucida Grande', Tahoma, Verdana, Arial, Helvetica, sans-serif;">100毫秒</span>  
  11. 106    }  
[java] view plain copy
 print?
  1. private class More ...SyncHandler extends Handler {  
  2. 47         @Override  
  3. 48         public void More ...handleMessage(Message msg) {  
  4. 49             if (msg.what == SYNC_MESSAGE) {  
  5. 50                 if (DebugFlags.WEB_SYNC_MANAGER) {  
  6. 51                     Log.v(LOGTAG, "*** WebSyncManager sync ***");  
  7. 52                 }  
  8. 53                 syncFromRamToFlash();  
  9. 54   
  10. 55                 // send a delayed message to request sync later  
  11. 56                 Message newmsg = obtainMessage(SYNC_MESSAGE);  
  12. 57                 sendMessageDelayed(newmsg, SYNC_LATER_INTERVAL);  
  13. 58             }  
  14. 59         }  
  15. 60     }  


[java] view plain copy
 print?
  1. protected void More ...syncFromRamToFlash() {  
  2.          if (DebugFlags.COOKIE_SYNC_MANAGER) {  
  3.              Log.v(LOGTAG, "CookieSyncManager::syncFromRamToFlash STARTS");  
  4.         }  
  5.   
  6.         CookieManager manager = CookieManager.getInstance();  
  7.   
  8.         if (!manager.acceptCookie()) {  
  9.             return;  
  10.         }  
  11.   
  12.         manager.flushCookieStore();  
  13.   
  14.         if (DebugFlags.COOKIE_SYNC_MANAGER) {  
  15.             Log.v(LOGTAG, "CookieSyncManager::syncFromRamToFlash DONE");  
  16.         }  
  17.     }  


在android5.0系统上Sync回调用flush()方法


[java] view plain copy
 print?
  1.  @Deprecated  
  2. 115    protected void More ...syncFromRamToFlash() {  
  3. 116        CookieManager.getInstance().flush();  
  4. 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。


0 0
原创粉丝点击