HttpURLConnection(java.net.CookieManager)和WebView(android.webkit.CookieManager)之间的Cookie的双向同步

不幸的是,Android上有大量的Cookiepipe理器。 HttpURLConnection的Cookie由java.net.CookieManager维护, WebView的Cookie由android.webkit.CookieManager维护。 这些Cookie存储库是分开的,需要手动同步。

我的应用程序使用HttpURLConnections和显示WebViews (这是一个本地HTML混合)。 当然,我希望分享所有的cookies,所以我会有一个透明的会议。

进一步来说:

  1. 当在HttpURLConnection中设置/更改cookie时,我希望WebViews也能看到这个改变。
  2. 当在WebView中设置/更改cookie时,我希望下一个HttpURLConnections也能看到这个改变。

简单地说 – 我正在寻找一个双向同步。 或者甚至更好,让他们都使用相同的cookie存储库。 你可以假设两者都在同一时间活跃(如在不同的标签)。

问题:

  1. 有没有办法使两个使用相同的Cookie存储库?

  2. 如果不是的话,build议做什么手动同步? 什么时候我应该同步和如何?

相关问题:这个问题解决了类似的问题,但只实现单向同步(HttpURLConnection – > WebView)。

我迄今为止的最佳想法:我真的想要避免手动同步,所以我试图考虑如何使两个使用同一个存储库。 也许我可以创build我自己的扩展java.net.CookieManager的核心处理程序。 我将使用java.net.CookieHandler.setDefault()将其设置为核心cookie处理程序。 它的实现将是android.webkit.CookieManager处理程序实例的代理(对于每个函数,我将简单地访问webkitpipe理器)。

Solutions Collecting From Web of "HttpURLConnection(java.net.CookieManager)和WebView(android.webkit.CookieManager)之间的Cookie的双向同步"

我已经实现了我自己的想法。 这实际上很酷。 我创build了自己的java.net.CookieManager实现,它将所有请求转发给WebViews的webkit android.webkit.CookieManager 。 这意味着不需要同步,HttpURLConnection使用 WebViews 相同的 cookie存储。

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

testing

我最初的testing显示这个工作正常。 我看到在WebViews和HttpURLConnection之间共享的cookies。 我希望我不会遇到任何问题。 如果您尝试了解并发现任何问题,请发表评论。