2012-12-15 117 views
9

我在我的應用程序中調用onCreate中的CookieManager.getInstance()。removeAllCookie()。CookieManager.getInstance()。removeAllCookie();不會刪除所有Cookie

我遇到了一個奇怪的問題,我看到一個意外的cookie值在GET請求中傳遞。事實上,cookie值是一個真正的舊值。

這裏是我的測試執行的步驟:

  1. 安裝應用
  2. 就應用程序啓動的GET請求。請求應該是乾淨的:不應該發送cookie。
  3. GET請求用Set-Cookie做出響應。該值基於請求時間,所以這個值在任何兩個請求中都是相同的。
  4. 發出另一個GET請求。請求應從步驟3發送cookie值。

我第一次安裝應用程序時,Cookie行爲按照我上面的預期工作。我卸載了該應用程序,然後重新安裝了該應用程序,並且Cookie行爲再次按預期工作。我做了幾次,事情很好,很好。

然後,突然,在第N次安裝時,第2步沒有通過。第一個GET請求不乾淨。實際上,它的值是在第一次安裝應用時設置的。

我無法可靠地重現此問題,但我經常看到它。這並不是說第一個安裝GET請求是從前一次安裝中發送一個cookie值 - 該值是來自之前的三次或四次安裝,其後所有安裝都是卸載

我看到這個怎麼可能?我如何實際上刪除所有的應用程序的Cookie?

回答

8

這是一個在黑暗中拍攝,但也許從你的第一餅乾裝在永久存儲,而從重新安裝那些在RAM緩存。也許刪除所有cookie的行爲由於某種原因沒有被同步到永久存儲器,因此它會在重新安裝之間保留舊值。

報價爲CookieSyncManager(重點煤礦)的文檔:

的CookieSyncManager用於同步RAM和永久存儲之間的瀏覽器cookie存儲。爲了獲得最佳性能,瀏覽器cookie被保存在RAM中。 A 單獨線程之間保存的Cookie,由計時器驅動。

...

同步間隔爲5分鐘,這樣你將要強制同步手動無論如何,例如在onPageFinished(WebView中,字符串)。請注意,即使同步()異步發生,所以不這樣做,就像您的活動正在關閉

這強烈暗示,當應用程序被卸載時,可能(在您的測試中,我假設這些測試有時間隔小於5分鐘)尚未同步,因此舊在這一點上,第一次安裝仍然在持久存儲中。如果5分鐘間隔沒有通過,我也沒有理由認爲在卸載過程中會發生同步。

這留下了一個問題:爲什麼有時候會發送一些cookie,即使您在onCreate中清除了它們?原來removeAllCookieis also asynchronous - 有時它會在你發出第一個請求之前完成,有時不會發生,而在後一種情況下,它會發送仍然有效的值:第一次安裝的值仍然在持久存儲。 (請注意,我仍在學習Android開發,並且我的一些假設可能是錯誤的 - 關於如何管理cookie以及在activity's lifecycle中的一個狀態中進行的異步調用是否可能仍未完成時另一個運行;但是這種解釋與您所描述的行爲非常一致)

0

嘗試下面的代碼:

BasicHttpContext mHttpContext;

CookieStore mCookieStore; 
String persistentcookie; 
CookieManager cookieManager; 
CookieSyncManager syncManager; 
private MultipartEntity m_hsmpeMultipartReqEntity; 

    //manages the session of the webview for the image uploading on the server. 
syncManager = CookieSyncManager.createInstance(m_hswvWebView.getContext()); 
syncManager.startSync(); 
cookieManager = CookieManager.getInstance(); 
boolean cok=cookieManager.acceptCookie(); // Here your cookie 
persistentcookie=cookieManager.getCookie("http://www.xxxx.com/");  
String[] splitstr=pat.split(persistentcookie.toString()); 
String key=splitstr[0]; // Key of the Cookie 
String value=splitstr[1]; //Session id 
m_hshttpClient = new DefaultHttpClient(); 
mHttpContext = new BasicHttpContext(); 
mCookieStore = m_hshttpClient.getCookieStore();   

BasicClientCookie clientcookie=new BasicClientCookie(key,value); 
clientcookie.setDomain(「www.xxxx.com」); // set the proper Domain URL 
mCookieStore.addCookie(clientcookie);    
m_hshttppostRequest = new HttpPost(「http://www.xxxx.com/"); 
// post URL after setting    cookie value. 

//set the cookie attribute in the BasicHTTPContext. 

mHttpContext.setAttribute(ClientContext.COOKIE_STORE, mCookieStore); 
m_hsmpeMultipartReqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE); 

m_hshttppostRequest.setEntity (m_hsmpeMultipartReqEntity); 
m_hshttpResponse = m_hshttpClient.execute(m_hshttppostRequest,mHttpContext); 
1

請在CookieManager.getInstance()。removeAllCookie()調用後立即調用CookieSyncManager.getInstance()。sync()。

原因是@mgibsonbr所提到的,一個單獨的線程在一個定時器的驅動下保存cookie,所以爲了讓它持久化,請立即直接調用CookieSyncManager.getInstance()。sync()。

-1
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) { 
     CookieManager.getInstance().removeAllCookies(null); 
    } else { 

     CookieSyncManager.createInstance(context); 
     CookieManager cookieManager = CookieManager.getInstance(); 
     if (cookieManager != null) { 
      cookieManager.removeAllCookie(); 
     } 
CookieSyncManager.getInstance().sync(); 
} 
+0

歡迎來到SO。請只填寫代碼答案。請參閱http://stackoverflow.com/help/how-to-answer –