我需要将具有本机登录屏幕的应用程序与在webview(混合应用程序)中运行的应用程序的其余部分集成。这听起来像是一种常见的方法但我在将会话数据(cookie)从本机代码传输到webview时遇到问题,我认为这与CookieManager的异步行为有关。
有时,在某些设备上,Cookie被删除或未应用。 从我读过的内容可能是因为removeSessionCookie,setCookie和sync在他们自己的线程中异步运行。我不太了解Java来自其他编程语言,因为似乎没有任何钩子知道什么时候任务完成EG回调,事件,asyc / await等。
所以问题是你怎么知道Android / Java中的异步任务何时完成? 我遇到了synchronized块语法,但看起来它不会像removeSessionCookie那样等待完成。
我的代码看起来有点像这样:
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.removeSessionCookie(); // problem
CookieSyncManager.getInstance().sync(); // maybe problem
List<Cookie> cookies = httpClient.getCookieStore().getCookies();
for (int i = 0; i < cookies.size(); i++) {
Cookie cookie = cookies.get(i);
String cookieString = cookie.getName() + "=" + cookie.getValue();
cookieManager.setCookie(url, cookieString);
}
CookieSyncManager.getInstance().sync();
答案 0 :(得分:4)
不幸的是,CookieManager
API设计使这很难/不可能。 CookieSyncManager
在这里根本不相关;它只处理内存中cookie数据库和存储在磁盘上的数据库之间的同步。在其上拨打sync()
不会有任何区别; WebView
和CookieManager
都已共享内存数据库,并在实际发生时立即查看彼此的更改。
通常,异步方法会提供某种回调或等待它完成的方式,但removeSessionCookie()
却没有。实际上在经典的WebView(从Honeycomb到JB)的某些版本的代码中实现了这样的方法,但它不是公共API方法,你必须通过反射访问它,它不能在新的WebView上工作在KK及以上。如果你真的想打电话给它,那就是void waitForCookieOperationsToComplete()
,但我不会建议它。
为什么你首先打电话给removeSessionCookie()
?最简单的解决方法是不使用它; CookieManager
API的其余部分的行为与您期望的一样。您也无需明确调用CookieSyncManager.sync()
。如果您遇到导致添加这些调用的问题,或者是否从某处复制过它们?
如果您支持较旧的操作系统版本,则会更加复杂;从Cupcake到Gingerbread,CookieManager
使用的网络堆栈不同,API的行为也不同,因此实际上有三个版本要定位:直到Gingerbread,Honeycomb通过Jellybean,然后是KitKat和更高版本..
答案 1 :(得分:1)
创建自己的java.net.CookieManager实现,它将所有请求转发给WebViews&#39; webkit android.webkit.CookieManager。这意味着不需要同步,HttpURLConnection使用与WebViews相同的cookie存储。