Using Cookies across Activities when using HttpClient
CookieManager
is used by the Java's internal HTTP client. It has nothing to do with Apache HttpClient.
In your code you always create for each request a new instance of HttpClient
and therefore a new CookieStore
instance, which obviously gets garbage collected along with all cookies stored in as soon as that HttpClient
instance goes out of scope.
You should either
(1) Re-use the same instance of HttpClient
for all logically related HTTP requests and share it between all logically related threads (which is the recommended way of using Apache HttpClient)
(2) or, at the very least, share the same instance of CookieStore
between logically related threads
(3) or, if you insist on using CookieManager
to store all your cookies, create a custom CookieStore
implementation backed by CookieManager
(As promised a solution to this. I still don't like it and feel like I'm missing out on the "Correct" way of doing this but, it works.)
You can use the CookieManager
to register your cookies (and therefore make these cookies available between apps) with the following code:
Saving cookies into the CookieManager
:
List<Cookie> cookies = httpClient.getCookieStore().getCookies();if(cookies != null){ for(Cookie cookie : cookies) { String cookieString = cookie.getName() + "=" + cookie.getValue() + "; domain=" + cookie.getDomain(); CookieManager.getInstance().setCookie(cookie.getDomain(), cookieString); }}CookieSyncManager.getInstance().sync();
Checking for cookies on specified domain:if(CookieManager.getInstance().getCookie(URI_FOR_DOMAIN)
To reconstruct values for HttpClient:
DefaultHttpClient httpClient = new DefaultHttpClient(params);String[] keyValueSets = CookieManager.getInstance().getCookie(URI_FOR_DOMAIN).split(";");for(String cookie : keyValueSets){ String[] keyValue = cookie.split("="); String key = keyValue[0]; String value = ""; if(keyValue.length>1) value = keyValue[1]; httpClient.getCookieStore().addCookie(new BasicClientCookie(key, value));}
In my application server wants to use same session with same cookies... After few hours of "googling" and painful headache I just saved cookies to SharedPreference or just put in some object and set DefaultHttpClient with same cookies again ... onDestroy just remove SharedPreferences ... that's all:
- First copy SerializableCookie class to your package:SerializableCookie
Look the following example:
public class NodeServerTask extends AsyncTask<Void, Void, String> {private DefaultHttpClient client;protected String doInBackground(Void... params) { HttpPost httpPost = new HttpPost(url); List<NameValuePair> urlParameters = new ArrayList<NameValuePair>(); urlParameters.add(nameValuePair); try { httpPost.setEntity(new UrlEncodedFormEntity(urlParameters)); List<Cookie> cookies = loadSharedPreferencesCookie(); if (cookies!=null){ CookieStore cookieStore = new BasicCookieStore(); for (int i=0; i<cookies.size(); i++) cookieStore.addCookie(cookies.get(i)); client.setCookieStore(cookieStore); } HttpResponse response = client.execute(httpPost); cookies = client.getCookieStore().getCookies(); saveSharedPreferencesCookies(cookies);
// two methods to save and load cookies ...
private void saveSharedPreferencesCookies(List<Cookie> cookies) { SerializableCookie[] serializableCookies = new SerializableCookie[cookies.size()]; for (int i=0;i<cookies.size();i++){ SerializableCookie serializableCookie = new SerializableCookie(cookies.get(i)); serializableCookies[i] = serializableCookie; } SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); SharedPreferences.Editor editor = preferences.edit(); ObjectOutputStream objectOutput; ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream(); try { objectOutput = new ObjectOutputStream(arrayOutputStream); objectOutput.writeObject(serializableCookies); byte[] data = arrayOutputStream.toByteArray(); objectOutput.close(); arrayOutputStream.close(); ByteArrayOutputStream out = new ByteArrayOutputStream(); Base64OutputStream b64 = new Base64OutputStream(out, Base64.DEFAULT); b64.write(data); b64.close(); out.close(); editor.putString("cookies", new String(out.toByteArray())); editor.apply(); } catch (IOException e) { e.printStackTrace(); }}private List<Cookie> loadSharedPreferencesCookie() { SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); byte[] bytes = preferences.getString("cookies", "{}").getBytes(); if (bytes.length == 0 || bytes.length==2) return null; ByteArrayInputStream byteArray = new ByteArrayInputStream(bytes); Base64InputStream base64InputStream = new Base64InputStream(byteArray, Base64.DEFAULT); ObjectInputStream in; List<Cookie> cookies = new ArrayList<Cookie>(); SerializableCookie[] serializableCookies; try { in = new ObjectInputStream(base64InputStream); serializableCookies = (SerializableCookie[]) in.readObject(); for (int i=0;i<serializableCookies.length; i++){ Cookie cookie = serializableCookies[i].getCookie(); cookies.add(cookie); } return cookies; } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } return null;}
Google Luck