La sincronización bidireccional para las cookies entre HttpURLConnection (java.net.CookieManager) y WebView (android.webkit.CookieManager)
Desafortunadamente, hay una multitud de administradores de cookies para Android. Las cookies para HttpURLConnection
son mantenidas por java.net.CookieManager
y las cookies para WebView
son mantenidas por android.webkit.CookieManager
. Estos repositorios de cookies son independientes y requieren sincronización manual.
Mi aplicación utiliza HttpURLConnections
y muestra WebViews
(es un híbrido nativo-HTML). Naturalmente, quiero compartir las cookies, así que tendré una sesión transparente en todas partes.
- Java.io.IOException: final inesperado de la secuencia
- Enviando cadena UTF-8 usando HttpURLConnection
- Java HttpURLConnection VS Android HttpURLConnection
- Android FileNotFound Exception - No se puede getInputStream desde la URL de la imagen que no tiene formato de archivo
- Android: intentando obtener datos de youtube api
Más específicamente:
- Cuando una cookie es establecida / cambiada en una HttpURLConnection, quiero que las WebViews vean este cambio también.
- Cuando se configura / cambia una cookie en un WebView, quiero que las siguientes HttpURLConnections vean este cambio también.
En pocas palabras – estoy buscando una sincronización bidireccional. O incluso mejor, hacer que ambos usen el mismo repositorio de cookies. Puede asumir que ambos están activos al mismo tiempo (como en diferentes pestañas).
Preguntas:
-
¿Hay alguna manera de hacer que ambos usen el mismo repositorio de cookies?
-
Si no, ¿cuál es la práctica recomendada para realizar la sincronización manual? ¿Cuándo debo sincronizar exactamente y cómo?
Pregunta relacionada: Esta pregunta aborda un problema similar, pero sólo implementa la sincronización unidireccional (HttpURLConnection -> WebView).
Mi mejor idea hasta el momento: Realmente quiero evitar una sincronización manual, así que traté de pensar cómo hacer que ambos usen el mismo repositorio. Tal vez pueda crear mi propio controlador central que extienda java.net.CookieManager
. Lo estableceré como el manejador de la galleta principal usando java.net.CookieHandler.setDefault()
. Su implementación será un proxy para la instancia del manejador android.webkit.CookieManager
(para cada función accederé simplemente al administrador de webkit).
- Android: java.net.protocolException no admite salida
- HttpURLConnection leyó InputStream dos veces
- HttpURLConnection: java.lang.IllegalStateException: Ya conectado
- HttpURLConnection con POST "time out" en ICS, funciona en HC
- HttpURLConnections persistentes en Android
- Android: Cómo iniciar sesión en la página web mediante programación, mediante HttpsURLConnection
- Java.io.IOException: El desafío de autenticación recibido es nulo en ICS 4.0.3
- ¿Qué devuelve el método getResponseMessage () de HttpURLConnection?
He implementado mi propia idea. En realidad, es genial. He creado mi propia implementación de java.net.CookieManager
que reenvía todas las solicitudes al webkit de WebViews android.webkit.CookieManager
. Esto significa que no se requiere sincronización y HttpURLConnection utiliza el mismo almacenamiento de cookies que las WebViews.
Clase 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(); } }
Y úselo haciendo esto en la inicialización de la aplicación:
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);
Pruebas
Mi prueba inicial muestra que esto está funcionando bien. Veo las cookies compartidas entre las WebViews y HttpURLConnection. Espero no tener problemas. Si lo prueba y descubre cualquier problema, por favor comente.
- ¿Hay una manera de ocultar la barra del sistema en Android 3.0? Es un dispositivo interno y estoy gestionando la navegación
- Puntero nulo Excepción – findViewById ()