Intereting Posts
Android, что делает атрибут clipToPadding? Android HTML5 – мягкая клавиатура перекрывает входное поле Отформатируйте относительную дату в формате, удобочитаемом человеком, на Android, используя Android DateUtils API Java: масштабирование карты Mapsforge при использовании онлайн-растровых изображений вместо автономного рендеринга Идентификатор ресурса не найден для атрибута 'parentActivityName' в пакете 'android' Создание настраиваемого макета для настроек Как ускорить эмуляцию Android? Поддерживаемые размеры предварительного просмотра камер для популярных телефонов Android Что такое переменные «shadow $ _klass_» и «shadow $ _monitor_» для java.lang.Object? Утечка памяти класса ClassLoader Установить изображение из android.R.drawable в режиме просмотра изображений Просмотр курсора базы данных Android Удалить Logcat с точки зрения Java Как построить android cts? И как добавить и запустить тестовый пример? Существуют ли соглашения о том, как назвать ресурсы?

Двухсторонняя синхронизация файлов cookie между HttpURLConnection (java.net.CookieManager) и WebView (android.webkit.CookieManager)

К сожалению, для Android существует множество менеджеров файлов cookie. HttpURLConnection cookie для HttpURLConnection поддерживаются java.net.CookieManager и файлы cookie для WebView поддерживаются android.webkit.CookieManager . Эти хранилища файлов cookie являются отдельными и требуют ручной синхронизации.

Мое приложение использует как HttpURLConnections и показывает WebViews (это гибрид native-HTML). Естественно, я хочу, чтобы обойти все файлы cookie – так что у меня будет прозрачный сеанс.

Более конкретно:

  1. Когда cookie устанавливается / изменен в HttpURLConnection, я хочу, чтобы WebViews также видел это изменение.
  2. Когда cookie установлен / изменен в WebView, я хочу, чтобы следующие HttpURLConnections также увидели это изменение.

Проще говоря – я ищу двухстороннюю синхронизацию. Или еще лучше, чтобы они использовали один и тот же репозиторий файлов cookie. Вы можете предположить, что оба они активны в одно и то же время (например, на разных вкладках).

Вопросов:

  1. Есть ли способ заставить использовать один и тот же репозиторий файлов cookie?

  2. Если нет, то в чем рекомендуемая практика ручной синхронизации? Когда нужно точно синхронизировать и как?

Связанный с этим вопрос: этот вопрос решает аналогичную проблему, но только реализует одностороннюю синхронизацию (HttpURLConnection -> WebView).

Моя лучшая идея до сих пор: я действительно хочу избежать ручной синхронизации, поэтому я попытался подумать, как заставить использовать один и тот же репозиторий. Может быть, я могу создать свой собственный основной обработчик, который расширяет java.net.CookieManager . Я установлю его как основной обработчик cookie с помощью java.net.CookieHandler.setDefault() . Его реализация будет прокси-сервером для экземпляра обработчика android.webkit.CookieManager (для каждой функции я просто займусь менеджером веб-китов).

Solutions Collecting From Web of "Двухсторонняя синхронизация файлов cookie между HttpURLConnection (java.net.CookieManager) и WebView (android.webkit.CookieManager)"

Я реализовал свою собственную идею. На самом деле это довольно круто. Я создал свою собственную реализацию java.net.CookieManager которая перенаправляет все запросы в webkit WebViews android.webkit.CookieManager . Это означает, что синхронизация не требуется, и HttpURLConnection использует то же хранилище файлов cookie, что и WebView.

Класс 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(); } } 

И используйте его, выполнив это при инициализации вашего приложения:

 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); 

тестирование

Мое начальное тестирование показывает, что это хорошо работает. Я вижу файлы cookie, общие между WebViews и HttpURLConnection. Надеюсь, у меня не возникнут проблемы. Если вы попробуете это и обнаружите какие-либо проблемы, прокомментируйте.