不幸的是,有大量的cookie经理的Android。该饼干的HttpURLConnection
是由 java.net.CookieManager
维护和饼干的的WebView
是由 android.webkit.CookieManager 。这些cookie的存储库是独立的,需要手动同步。
Unfortunately, there's a multitude of cookie managers for Android. The cookies for HttpURLConnection
are maintained by java.net.CookieManager
and the cookies for WebView
are maintained by android.webkit.CookieManager
. These cookie repositories are separate and require manual synchronization.
我的应用程序同时使用 HttpURLConnections
和表演 WebViews
(这是一个纯HTML混合动力)。当然,我希望同时共享所有Cookie - 所以我将有一个透明的会话中的所有跨
My app uses both HttpURLConnections
and shows WebViews
(it's a native-HTML hybrid). Naturally, I want both to share all cookies - so I will have a transparent session all across.
更具体:
当一个Cookie设置/在HttpURLConnection的改变,我想WebViews看到这种改变。 当一个Cookie设置/在一个web视图改变了,我想接下来的HttpURLConnections看到这样的改变。简单地说 - 我在寻找一个双向同步。甚至更好,让他们都使用相同的cookie存储库。你可以假设这两个活跃在同一时间(如在不同的选项卡)。
Simply put - I'm looking for a two-way sync. Or even better, to have them both use the same cookie repository. You can assume both are active in the same time (like on different tabs).
问题:
有没有一种方法,使两者都使用相同的cookie库?
Is there a way to make both use the same cookie repository?
如果不是,有什么建议的做法做了手动同步?正是时候,我应该同步又如何呢?
If not, what is the recommended practice to do the manual sync? When exactly should I sync and how?
相关问题::该question铲球类似的问题,但只能实现单向同步(HttpURLConnection类 - > web视图)
Related Question: This question tackles a similar issue, but only implements one-way sync (HttpURLConnection -> WebView).
我的最佳创意至今:我真的想避免手动同步,所以我试图去思考如何使两者使用相同的存储库。也许我可以创造我自己的核心处理器延伸 java.net.CookieManager
。我将其设置为使用核心cookie处理程序 java.net.CookieHandler.setDefault()
。它的实施将是在 android.webkit.CookieManager
处理程序实例(每一个功能,我会简单地访问WebKit的经理)的代理。
My Best Idea So Far: I really want to avoid a manual sync, so I tried to think how to make both use the same repository. Maybe I can create my own core handler which extends java.net.CookieManager
. I will set it as the core cookie handler using java.net.CookieHandler.setDefault()
. Its implementation will be a proxy to the android.webkit.CookieManager
handler instance (for every function I'll simply access the webkit manager).
推荐答案
我实现我自己的想法。它实际上是pretty的凉爽。我已经创建了自己的实施 java.net.CookieManager
的这一切转发请求到WebViews的webkit android.webkit.CookieManager
。这意味着,没有同步是必需的,HttpURLConnection的使用的一样的的cookie存储作为WebViews。
I've implemented my own idea. It's actually pretty cool. I've created my own implementation of java.net.CookieManager
which forwards all requests to the WebViews' webkit android.webkit.CookieManager
. This means no sync is required and HttpURLConnection uses the same cookie storage as the WebViews.
类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);
测试
我的初步测试表明,这是运作良好。我看到WebViews和HttpURLConnection类之间共享的cookies。我希望我不会遇到任何问题。如果你尝试了这一点,并发现有任何问题,请评论。
My initial testing show this is working well. I see cookies shared between the WebViews and HttpURLConnection. I hope I'll not run into any issues. If you try this out and discover any problem, please comment.
相关推荐
最新文章