Dwukierunkowa synchronizacja plików cookie między HttpURLConnection (java.net.CookieManager) i WebView (android.webkit.CookieManager)
Niestety, istnieje wiele menedżerów plików cookie dla Androida. Pliki cookie dla HttpURLConnection
są utrzymywane przez java.net.CookieManager
, A pliki cookie dla WebView
są utrzymywane przez android.webkit.CookieManager
. Te repozytoria plików cookie są oddzielne i wymagają ręcznej synchronizacji.
Moja aplikacja używa zarówno HttpURLConnections
, jak i pokazuje WebViews
(jest hybrydą natywnego HTML). Oczywiście chcę, aby obie strony udostępniały wszystkie pliki cookie - więc będę mieć przejrzystą sesję na całym świecie.
Dokładniej:
- gdy a plik cookie jest ustawiany/zmieniany w połączeniu HttpURLConnection, chcę, aby WebViews również widział tę zmianę.
- gdy plik cookie jest ustawiany/zmieniany w widoku sieci Web, chcę, aby następne połączenia HttpURLConnections również zobaczyły tę zmianę.
Mówiąc najprościej-Szukam dwukierunkowej synchronizacji. Albo jeszcze lepiej, aby oboje korzystali z tego samego repozytorium plików cookie. Można założyć, że oba są aktywne w tym samym czasie(jak na różnych kartach).
Pytania:
Czy jest sposób na czy obie strony korzystają z tego samego repozytorium plików cookie?
Jeśli nie, Jaka jest zalecana praktyka wykonywania ręcznej synchronizacji? Kiedy dokładnie powinienem synchronizować i jak?
Podobne pytanie: to pytanie rozwiązuje podobny problem, ale implementuje tylko synchronizację jednokierunkową (HttpURLConnection- > WebView).
Mój najlepszy jak dotąd pomysł: naprawdę chcę uniknąć ręcznej synchronizacji, więc próbowałem pomyśleć, jak sprawić, by obie używały tego samego repozytorium. Może uda mi się stworzyć mój własny program obsługi rdzenia, który rozszerza java.net.CookieManager
. Ustawię go jako główny mechanizm obsługi plików cookie za pomocą java.net.CookieHandler.setDefault()
. Jego implementacja będzie proxy do instancji android.webkit.CookieManager
handler (dla każdej funkcji po prostu uzyskam dostęp do webkit managera).
1 answers
Wdrożyłem swój własny pomysł. To całkiem fajne. Stworzyłem własną implementację java.net.CookieManager
, która przekazuje wszystkie żądania do webkit android.webkit.CookieManager
WebViews. Oznacza to, że nie jest wymagana Synchronizacja, A HttpURLConnection używa tego samego przechowywania plików cookie, co WebViews.
Class WebkitCookieManagerProxy:
import java.io.IOException;
import java.net.CookieManager;
import java.net.CookiePolicy;
import java.net.CookieStore;
import java.net.URI;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
public class WebkitCookieManagerProxy extends CookieManager
{
private android.webkit.CookieManager webkitCookieManager;
public WebkitCookieManagerProxy()
{
this(null, null);
}
public WebkitCookieManagerProxy(CookieStore store, CookiePolicy cookiePolicy)
{
super(null, cookiePolicy);
this.webkitCookieManager = android.webkit.CookieManager.getInstance();
}
@Override
public void put(URI uri, Map<String, List<String>> responseHeaders) throws IOException
{
// make sure our args are valid
if ((uri == null) || (responseHeaders == null)) return;
// save our url once
String url = uri.toString();
// go over the headers
for (String headerKey : responseHeaders.keySet())
{
// ignore headers which aren't cookie related
if ((headerKey == null) || !(headerKey.equalsIgnoreCase("Set-Cookie2") || headerKey.equalsIgnoreCase("Set-Cookie"))) continue;
// process each of the headers
for (String headerValue : responseHeaders.get(headerKey))
{
this.webkitCookieManager.setCookie(url, headerValue);
}
}
}
@Override
public Map<String, List<String>> get(URI uri, Map<String, List<String>> requestHeaders) throws IOException
{
// make sure our args are valid
if ((uri == null) || (requestHeaders == null)) throw new IllegalArgumentException("Argument is null");
// save our url once
String url = uri.toString();
// prepare our response
Map<String, List<String>> res = new java.util.HashMap<String, List<String>>();
// get the cookie
String cookie = this.webkitCookieManager.getCookie(url);
// return it
if (cookie != null) res.put("Cookie", Arrays.asList(cookie));
return res;
}
@Override
public CookieStore getCookieStore()
{
// we don't want anyone to work with this cookie store directly
throw new UnsupportedOperationException();
}
}
I użyj go, wykonując to podczas inicjalizacji aplikacji:
android.webkit.CookieSyncManager.createInstance(appContext);
// unrelated, just make sure cookies are generally allowed
android.webkit.CookieManager.getInstance().setAcceptCookie(true);
// magic starts here
WebkitCookieManagerProxy coreCookieManager = new WebkitCookieManagerProxy(null, java.net.CookiePolicy.ACCEPT_ALL);
java.net.CookieHandler.setDefault(coreCookieManager);
Testowanie
Moje wstępne testy pokazują to działa dobrze. Widzę pliki cookie współdzielone między WebViews i HttpURLConnection. Mam nadzieję, że nie napotkam żadnych problemów. Jeśli wypróbujesz to i odkryjesz jakikolwiek problem, skomentuj.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-08 14:37:09